| Mikhail Glushenkov | b90cd83 | 2008-05-06 16:34:12 +0000 | [diff] [blame] | 1 | //===--- CompilationGraph.h - The LLVM Compiler Driver ----------*- C++ -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open | 
|  | 6 | // Source License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | //  Compilation graph - definition. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #ifndef LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H | 
|  | 15 | #define LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H | 
|  | 16 |  | 
|  | 17 | #include "AutoGenerated.h" | 
|  | 18 | #include "Tool.h" | 
|  | 19 |  | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/GraphTraits.h" | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/IntrusiveRefCntPtr.h" | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 22 | #include "llvm/ADT/iterator" | 
|  | 23 | #include "llvm/ADT/SmallVector.h" | 
| Mikhail Glushenkov | b90cd83 | 2008-05-06 16:34:12 +0000 | [diff] [blame] | 24 | #include "llvm/ADT/StringMap.h" | 
|  | 25 | #include "llvm/System/Path.h" | 
|  | 26 |  | 
| Mikhail Glushenkov | e0ff9ae | 2008-05-06 18:18:58 +0000 | [diff] [blame] | 27 | #include <cassert> | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 28 | #include <string> | 
|  | 29 |  | 
| Mikhail Glushenkov | be9d9a1 | 2008-05-06 18:08:59 +0000 | [diff] [blame] | 30 | namespace llvmc { | 
| Mikhail Glushenkov | b90cd83 | 2008-05-06 16:34:12 +0000 | [diff] [blame] | 31 |  | 
| Mikhail Glushenkov | e0ff9ae | 2008-05-06 18:18:58 +0000 | [diff] [blame] | 32 | // A wrapper for StringMap that provides set-like functionality. | 
|  | 33 | // Only insert() and count() methods are used by my code. | 
|  | 34 | template <class AllocatorTy = llvm::MallocAllocator> | 
|  | 35 | class StringSet : public llvm::StringMap<char, AllocatorTy> { | 
|  | 36 | typedef llvm::StringMap<char, AllocatorTy> base; | 
|  | 37 | public: | 
|  | 38 | void insert (const std::string& InLang) { | 
|  | 39 | assert(!InLang.empty()); | 
|  | 40 | const char* KeyStart = &InLang[0]; | 
|  | 41 | const char* KeyEnd = KeyStart + InLang.size(); | 
|  | 42 | base::insert(llvm::StringMapEntry<char>:: | 
|  | 43 | Create(KeyStart, KeyEnd, base::getAllocator(), '+')); | 
|  | 44 | } | 
|  | 45 | }; | 
|  | 46 | typedef StringSet<> InputLanguagesSet; | 
| Mikhail Glushenkov | 76b1b24 | 2008-05-06 18:15:12 +0000 | [diff] [blame] | 47 |  | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 48 | // An edge of the compilation graph. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 49 | class Edge : public llvm::RefCountedBaseVPTR<Edge> { | 
|  | 50 | public: | 
|  | 51 | Edge(const std::string& T) : ToolName_(T) {} | 
|  | 52 | virtual ~Edge() {}; | 
|  | 53 |  | 
|  | 54 | const std::string& ToolName() const { return ToolName_; } | 
| Mikhail Glushenkov | 76b1b24 | 2008-05-06 18:15:12 +0000 | [diff] [blame] | 55 | virtual unsigned Weight(const InputLanguagesSet& InLangs) const = 0; | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 56 | private: | 
|  | 57 | std::string ToolName_; | 
|  | 58 | }; | 
|  | 59 |  | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 60 | // Edges that have no properties are instances of this class. | 
| Mikhail Glushenkov | d752c3f | 2008-05-06 16:36:50 +0000 | [diff] [blame] | 61 | class SimpleEdge : public Edge { | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 62 | public: | 
| Mikhail Glushenkov | d752c3f | 2008-05-06 16:36:50 +0000 | [diff] [blame] | 63 | SimpleEdge(const std::string& T) : Edge(T) {} | 
| Mikhail Glushenkov | 76b1b24 | 2008-05-06 18:15:12 +0000 | [diff] [blame] | 64 | unsigned Weight(const InputLanguagesSet&) const { return 1; } | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 65 | }; | 
| Mikhail Glushenkov | b90cd83 | 2008-05-06 16:34:12 +0000 | [diff] [blame] | 66 |  | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 67 | // A node of the compilation graph. | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 68 | struct Node { | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 69 | // A Node holds a list of the outward edges. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 70 | typedef llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> container_type; | 
|  | 71 | typedef container_type::iterator iterator; | 
|  | 72 | typedef container_type::const_iterator const_iterator; | 
| Mikhail Glushenkov | b90cd83 | 2008-05-06 16:34:12 +0000 | [diff] [blame] | 73 |  | 
| Mikhail Glushenkov | c74bfc9 | 2008-05-06 17:26:53 +0000 | [diff] [blame] | 74 | Node() : OwningGraph(0), InEdges(0) {} | 
|  | 75 | Node(CompilationGraph* G) : OwningGraph(G), InEdges(0) {} | 
|  | 76 | Node(CompilationGraph* G, Tool* T) : | 
|  | 77 | OwningGraph(G), ToolPtr(T), InEdges(0) {} | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 78 |  | 
| Mikhail Glushenkov | d752c3f | 2008-05-06 16:36:50 +0000 | [diff] [blame] | 79 | bool HasChildren() const { return !OutEdges.empty(); } | 
| Mikhail Glushenkov | 0260658 | 2008-05-06 18:07:14 +0000 | [diff] [blame] | 80 | const std::string Name() const | 
|  | 81 | { return ToolPtr ? ToolPtr->Name() : "root"; } | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 82 |  | 
| Mikhail Glushenkov | c74bfc9 | 2008-05-06 17:26:53 +0000 | [diff] [blame] | 83 | // Iteration. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 84 | iterator EdgesBegin() { return OutEdges.begin(); } | 
|  | 85 | const_iterator EdgesBegin() const { return OutEdges.begin(); } | 
|  | 86 | iterator EdgesEnd() { return OutEdges.end(); } | 
|  | 87 | const_iterator EdgesEnd() const { return OutEdges.end(); } | 
|  | 88 |  | 
| Mikhail Glushenkov | c74bfc9 | 2008-05-06 17:26:53 +0000 | [diff] [blame] | 89 | // Add an outward edge. Takes ownership of the Edge object. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 90 | void AddEdge(Edge* E) | 
|  | 91 | { OutEdges.push_back(llvm::IntrusiveRefCntPtr<Edge>(E)); } | 
|  | 92 |  | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 93 | // Inward edge counter. Used to implement topological sort. | 
|  | 94 | // TOTHINK: Move the mutable counter back into Tool classes? Makes | 
|  | 95 | // us more const-correct. | 
| Mikhail Glushenkov | c74bfc9 | 2008-05-06 17:26:53 +0000 | [diff] [blame] | 96 | void IncrInEdges() { ++InEdges; } | 
|  | 97 | void DecrInEdges() { --InEdges; } | 
|  | 98 | bool HasNoInEdges() const { return InEdges == 0; } | 
|  | 99 |  | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 100 | // Needed to implement NodeChildIterator/GraphTraits | 
|  | 101 | CompilationGraph* OwningGraph; | 
|  | 102 | // The corresponding Tool. | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 103 | // WARNING: ToolPtr can be NULL (for the root node). | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 104 | llvm::IntrusiveRefCntPtr<Tool> ToolPtr; | 
|  | 105 | // Links to children. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 106 | container_type OutEdges; | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 107 | // Inward edge counter. Updated in | 
|  | 108 | // CompilationGraph::insertEdge(). Used for topological sorting. | 
| Mikhail Glushenkov | c74bfc9 | 2008-05-06 17:26:53 +0000 | [diff] [blame] | 109 | unsigned InEdges; | 
| Mikhail Glushenkov | b90cd83 | 2008-05-06 16:34:12 +0000 | [diff] [blame] | 110 | }; | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 111 |  | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 112 | class NodesIterator; | 
|  | 113 |  | 
| Mikhail Glushenkov | 0260658 | 2008-05-06 18:07:14 +0000 | [diff] [blame] | 114 | // The compilation graph itself. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 115 | class CompilationGraph { | 
| Mikhail Glushenkov | 4f6e3a4 | 2008-05-06 17:28:03 +0000 | [diff] [blame] | 116 | // Main data structure. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 117 | typedef llvm::StringMap<Node> nodes_map_type; | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 118 | // These are used to map from language names to tools. (We can | 
|  | 119 | // have several tools associated with each language name, hence | 
|  | 120 | // the need for a vector of Edges.) | 
| Mikhail Glushenkov | 4f6e3a4 | 2008-05-06 17:28:03 +0000 | [diff] [blame] | 121 | typedef | 
|  | 122 | llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> tools_vector_type; | 
|  | 123 | typedef llvm::StringMap<tools_vector_type> tools_map_type; | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 124 |  | 
|  | 125 | // Map from file extensions to language names. | 
|  | 126 | LanguageMap ExtsToLangs; | 
|  | 127 | // Map from language names to lists of tool names. | 
|  | 128 | tools_map_type ToolsMap; | 
|  | 129 | // Map from tool names to Tool objects. | 
|  | 130 | nodes_map_type NodesMap; | 
|  | 131 |  | 
|  | 132 | public: | 
|  | 133 |  | 
|  | 134 | CompilationGraph(); | 
|  | 135 |  | 
| Mikhail Glushenkov | d752c3f | 2008-05-06 16:36:50 +0000 | [diff] [blame] | 136 | // insertVertex - insert a new node into the graph. Takes | 
|  | 137 | // ownership of the object. | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 138 | void insertNode(Tool* T); | 
|  | 139 |  | 
| Mikhail Glushenkov | d752c3f | 2008-05-06 16:36:50 +0000 | [diff] [blame] | 140 | // insertEdge - Insert a new edge into the graph. Takes ownership | 
| Mikhail Glushenkov | c74bfc9 | 2008-05-06 17:26:53 +0000 | [diff] [blame] | 141 | // of the Edge object. | 
| Mikhail Glushenkov | d752c3f | 2008-05-06 16:36:50 +0000 | [diff] [blame] | 142 | void insertEdge(const std::string& A, Edge* E); | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 143 |  | 
| Mikhail Glushenkov | d752c3f | 2008-05-06 16:36:50 +0000 | [diff] [blame] | 144 | // Build - Build target(s) from the input file set. Command-line | 
|  | 145 | // options are passed implicitly as global variables. | 
| Mikhail Glushenkov | 0260658 | 2008-05-06 18:07:14 +0000 | [diff] [blame] | 146 | int Build(llvm::sys::Path const& tempDir); | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 147 |  | 
|  | 148 | // Return a reference to the node correponding to the given tool | 
|  | 149 | // name. Throws std::runtime_error. | 
|  | 150 | Node& getNode(const std::string& ToolName); | 
|  | 151 | const Node& getNode(const std::string& ToolName) const; | 
|  | 152 |  | 
|  | 153 | // viewGraph - This function is meant for use from the debugger. | 
|  | 154 | // You can just say 'call G->viewGraph()' and a ghostview window | 
|  | 155 | // should pop up from the program, displaying the compilation | 
|  | 156 | // graph. This depends on there being a 'dot' and 'gv' program | 
|  | 157 | // in your path. | 
|  | 158 | void viewGraph(); | 
|  | 159 |  | 
|  | 160 | // Write a CompilationGraph.dot file. | 
|  | 161 | void writeGraph(); | 
|  | 162 |  | 
|  | 163 | // GraphTraits support | 
|  | 164 | friend NodesIterator GraphBegin(CompilationGraph*); | 
|  | 165 | friend NodesIterator GraphEnd(CompilationGraph*); | 
|  | 166 | friend void PopulateCompilationGraph(CompilationGraph&); | 
|  | 167 |  | 
|  | 168 | private: | 
|  | 169 | // Helper functions. | 
|  | 170 |  | 
|  | 171 | // Find out which language corresponds to the suffix of this file. | 
|  | 172 | const std::string& getLanguage(const llvm::sys::Path& File) const; | 
|  | 173 |  | 
|  | 174 | // Return a reference to the list of tool names corresponding to | 
|  | 175 | // the given language name. Throws std::runtime_error. | 
|  | 176 | const tools_vector_type& getToolsVector(const std::string& LangName) const; | 
| Mikhail Glushenkov | 2ba4c5a | 2008-05-06 17:25:51 +0000 | [diff] [blame] | 177 |  | 
| Mikhail Glushenkov | 4c11a62 | 2008-05-06 18:15:35 +0000 | [diff] [blame] | 178 | // Pass the input file through the toolchain starting at StartNode. | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 179 | void PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode, | 
| Mikhail Glushenkov | 76b1b24 | 2008-05-06 18:15:12 +0000 | [diff] [blame] | 180 | const InputLanguagesSet& InLangs, | 
| Mikhail Glushenkov | 35a85e8 | 2008-05-06 18:10:20 +0000 | [diff] [blame] | 181 | const llvm::sys::Path& TempDir) const; | 
| Mikhail Glushenkov | 2ba4c5a | 2008-05-06 17:25:51 +0000 | [diff] [blame] | 182 |  | 
| Mikhail Glushenkov | 0260658 | 2008-05-06 18:07:14 +0000 | [diff] [blame] | 183 | // Find head of the toolchain corresponding to the given file. | 
| Mikhail Glushenkov | 87416b4 | 2008-05-06 18:10:53 +0000 | [diff] [blame] | 184 | const Node* FindToolChain(const llvm::sys::Path& In, | 
| Mikhail Glushenkov | 76b1b24 | 2008-05-06 18:15:12 +0000 | [diff] [blame] | 185 | const std::string* forceLanguage, | 
|  | 186 | InputLanguagesSet& InLangs) const; | 
| Mikhail Glushenkov | 0260658 | 2008-05-06 18:07:14 +0000 | [diff] [blame] | 187 |  | 
| Mikhail Glushenkov | 4c11a62 | 2008-05-06 18:15:35 +0000 | [diff] [blame] | 188 | // Traverse the initial parts of the toolchains. | 
|  | 189 | void BuildInitial(InputLanguagesSet& InLangs, | 
|  | 190 | const llvm::sys::Path& TempDir); | 
|  | 191 |  | 
| Mikhail Glushenkov | 0260658 | 2008-05-06 18:07:14 +0000 | [diff] [blame] | 192 | // Sort the nodes in topological order. | 
|  | 193 | void TopologicalSort(std::vector<const Node*>& Out); | 
|  | 194 | // Call TopologicalSort and filter the resulting list to include | 
|  | 195 | // only Join nodes. | 
|  | 196 | void TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out); | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 197 | }; | 
|  | 198 |  | 
|  | 199 | /// GraphTraits support code. | 
|  | 200 |  | 
|  | 201 | // Auxiliary class needed to implement GraphTraits support.  Can be | 
|  | 202 | // generalised to something like value_iterator for map-like | 
|  | 203 | // containers. | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 204 | class NodesIterator : public llvm::StringMap<Node>::iterator { | 
|  | 205 | typedef llvm::StringMap<Node>::iterator super; | 
|  | 206 | typedef NodesIterator ThisType; | 
|  | 207 | typedef Node* pointer; | 
|  | 208 | typedef Node& reference; | 
|  | 209 |  | 
|  | 210 | public: | 
|  | 211 | NodesIterator(super I) : super(I) {} | 
|  | 212 |  | 
|  | 213 | inline reference operator*() const { | 
|  | 214 | return super::operator->()->second; | 
|  | 215 | } | 
|  | 216 | inline pointer operator->() const { | 
|  | 217 | return &super::operator->()->second; | 
|  | 218 | } | 
|  | 219 | }; | 
|  | 220 |  | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 221 | inline NodesIterator GraphBegin(CompilationGraph* G) { | 
|  | 222 | return NodesIterator(G->NodesMap.begin()); | 
|  | 223 | } | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 224 |  | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 225 | inline NodesIterator GraphEnd(CompilationGraph* G) { | 
|  | 226 | return NodesIterator(G->NodesMap.end()); | 
|  | 227 | } | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 228 |  | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 229 |  | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 230 | // Another auxiliary class needed by GraphTraits. | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 231 | class NodeChildIterator : public bidirectional_iterator<Node, ptrdiff_t> { | 
|  | 232 | typedef NodeChildIterator ThisType; | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 233 | typedef Node::container_type::iterator iterator; | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 234 |  | 
|  | 235 | CompilationGraph* OwningGraph; | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 236 | iterator EdgeIter; | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 237 | public: | 
|  | 238 | typedef Node* pointer; | 
|  | 239 | typedef Node& reference; | 
|  | 240 |  | 
|  | 241 | NodeChildIterator(Node* N, iterator I) : | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 242 | OwningGraph(N->OwningGraph), EdgeIter(I) {} | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 243 |  | 
|  | 244 | const ThisType& operator=(const ThisType& I) { | 
|  | 245 | assert(OwningGraph == I.OwningGraph); | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 246 | EdgeIter = I.EdgeIter; | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 247 | return *this; | 
|  | 248 | } | 
|  | 249 |  | 
|  | 250 | inline bool operator==(const ThisType& I) const | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 251 | { return EdgeIter == I.EdgeIter; } | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 252 | inline bool operator!=(const ThisType& I) const | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 253 | { return EdgeIter != I.EdgeIter; } | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 254 |  | 
|  | 255 | inline pointer operator*() const { | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 256 | return &OwningGraph->getNode((*EdgeIter)->ToolName()); | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 257 | } | 
|  | 258 | inline pointer operator->() const { | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 259 | return &OwningGraph->getNode((*EdgeIter)->ToolName()); | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 260 | } | 
|  | 261 |  | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 262 | ThisType& operator++() { ++EdgeIter; return *this; } // Preincrement | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 263 | ThisType operator++(int) { // Postincrement | 
|  | 264 | ThisType tmp = *this; | 
|  | 265 | ++*this; | 
|  | 266 | return tmp; | 
|  | 267 | } | 
|  | 268 |  | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 269 | inline ThisType& operator--() { --EdgeIter; return *this; }  // Predecrement | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 270 | inline ThisType operator--(int) { // Postdecrement | 
|  | 271 | ThisType tmp = *this; | 
|  | 272 | --*this; | 
|  | 273 | return tmp; | 
|  | 274 | } | 
|  | 275 |  | 
|  | 276 | }; | 
|  | 277 | } | 
|  | 278 |  | 
|  | 279 | namespace llvm { | 
|  | 280 | template <> | 
| Mikhail Glushenkov | be9d9a1 | 2008-05-06 18:08:59 +0000 | [diff] [blame] | 281 | struct GraphTraits<llvmc::CompilationGraph*> { | 
|  | 282 | typedef llvmc::CompilationGraph GraphType; | 
|  | 283 | typedef llvmc::Node NodeType; | 
|  | 284 | typedef llvmc::NodeChildIterator ChildIteratorType; | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 285 |  | 
|  | 286 | static NodeType* getEntryNode(GraphType* G) { | 
|  | 287 | return &G->getNode("root"); | 
|  | 288 | } | 
|  | 289 |  | 
|  | 290 | static ChildIteratorType child_begin(NodeType* N) { | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 291 | return ChildIteratorType(N, N->OutEdges.begin()); | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 292 | } | 
|  | 293 | static ChildIteratorType child_end(NodeType* N) { | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 294 | return ChildIteratorType(N, N->OutEdges.end()); | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 295 | } | 
|  | 296 |  | 
| Mikhail Glushenkov | be9d9a1 | 2008-05-06 18:08:59 +0000 | [diff] [blame] | 297 | typedef llvmc::NodesIterator nodes_iterator; | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 298 | static nodes_iterator nodes_begin(GraphType *G) { | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 299 | return GraphBegin(G); | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 300 | } | 
|  | 301 | static nodes_iterator nodes_end(GraphType *G) { | 
| Mikhail Glushenkov | 0a17493 | 2008-05-06 16:36:06 +0000 | [diff] [blame] | 302 | return GraphEnd(G); | 
| Mikhail Glushenkov | 0d08db0 | 2008-05-06 16:35:25 +0000 | [diff] [blame] | 303 | } | 
|  | 304 | }; | 
|  | 305 |  | 
| Mikhail Glushenkov | b90cd83 | 2008-05-06 16:34:12 +0000 | [diff] [blame] | 306 | } | 
|  | 307 |  | 
|  | 308 | #endif // LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H |