LLVM API Documentation
00001 //===--- CompilationGraph.h - The LLVM Compiler Driver ----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open 00006 // Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Compilation graph - definition. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H 00015 #define LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H 00016 00017 #include "llvm/CompilerDriver/Tool.h" 00018 00019 #include "llvm/ADT/GraphTraits.h" 00020 #include "llvm/ADT/IntrusiveRefCntPtr.h" 00021 #include "llvm/ADT/iterator.h" 00022 #include "llvm/ADT/SmallVector.h" 00023 #include "llvm/ADT/StringMap.h" 00024 #include "llvm/ADT/StringSet.h" 00025 #include "llvm/System/Path.h" 00026 00027 #include <cassert> 00028 #include <string> 00029 00030 namespace llvmc { 00031 00032 class CompilationGraph; 00033 typedef llvm::StringSet<> InputLanguagesSet; 00034 00035 /// LanguageMap - Maps from extensions to language names. 00036 class LanguageMap : public llvm::StringMap<std::string> { 00037 public: 00038 00039 /// GetLanguage - Find the language name corresponding to a given file. 00040 const std::string& GetLanguage(const llvm::sys::Path&) const; 00041 }; 00042 00043 /// Edge - Represents an edge of the compilation graph. 00044 class Edge : public llvm::RefCountedBaseVPTR<Edge> { 00045 public: 00046 Edge(const std::string& T) : ToolName_(T) {} 00047 virtual ~Edge() {}; 00048 00049 const std::string& ToolName() const { return ToolName_; } 00050 virtual unsigned Weight(const InputLanguagesSet& InLangs) const = 0; 00051 private: 00052 std::string ToolName_; 00053 }; 00054 00055 /// SimpleEdge - An edge that has no properties. 00056 class SimpleEdge : public Edge { 00057 public: 00058 SimpleEdge(const std::string& T) : Edge(T) {} 00059 unsigned Weight(const InputLanguagesSet&) const { return 1; } 00060 }; 00061 00062 /// Node - A node (vertex) of the compilation graph. 00063 struct Node { 00064 // A Node holds a list of the outward edges. 00065 typedef llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> container_type; 00066 typedef container_type::iterator iterator; 00067 typedef container_type::const_iterator const_iterator; 00068 00069 Node() : OwningGraph(0), InEdges(0) {} 00070 Node(CompilationGraph* G) : OwningGraph(G), InEdges(0) {} 00071 Node(CompilationGraph* G, Tool* T) : 00072 OwningGraph(G), ToolPtr(T), InEdges(0) {} 00073 00074 bool HasChildren() const { return !OutEdges.empty(); } 00075 const std::string Name() const 00076 { return ToolPtr ? ToolPtr->Name() : "root"; } 00077 00078 // Iteration. 00079 iterator EdgesBegin() { return OutEdges.begin(); } 00080 const_iterator EdgesBegin() const { return OutEdges.begin(); } 00081 iterator EdgesEnd() { return OutEdges.end(); } 00082 const_iterator EdgesEnd() const { return OutEdges.end(); } 00083 00084 /// AddEdge - Add an outward edge. Takes ownership of the provided 00085 /// Edge object. 00086 void AddEdge(Edge* E); 00087 00088 // Inward edge counter. Used to implement topological sort. 00089 void IncrInEdges() { ++InEdges; } 00090 void DecrInEdges() { --InEdges; } 00091 bool HasNoInEdges() const { return InEdges == 0; } 00092 00093 // Needed to implement NodeChildIterator/GraphTraits 00094 CompilationGraph* OwningGraph; 00095 // The corresponding Tool. 00096 // WARNING: ToolPtr can be NULL (for the root node). 00097 llvm::IntrusiveRefCntPtr<Tool> ToolPtr; 00098 // Links to children. 00099 container_type OutEdges; 00100 // Inward edge counter. Updated in 00101 // CompilationGraph::insertEdge(). Used for topological sorting. 00102 unsigned InEdges; 00103 }; 00104 00105 class NodesIterator; 00106 00107 /// CompilationGraph - The compilation graph itself. 00108 class CompilationGraph { 00109 /// nodes_map_type - The main data structure. 00110 typedef llvm::StringMap<Node> nodes_map_type; 00111 /// tools_vector_type, tools_map_type - Data structures used to 00112 /// map from language names to tools. (We can have several tools 00113 /// associated with each language name, hence the need for a 00114 /// vector.) 00115 typedef 00116 llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> tools_vector_type; 00117 typedef llvm::StringMap<tools_vector_type> tools_map_type; 00118 00119 /// ToolsMap - Map from language names to lists of tool names. 00120 tools_map_type ToolsMap; 00121 /// NodesMap - Map from tool names to Tool objects. 00122 nodes_map_type NodesMap; 00123 00124 public: 00125 00126 typedef nodes_map_type::iterator nodes_iterator; 00127 typedef nodes_map_type::const_iterator const_nodes_iterator; 00128 00129 CompilationGraph(); 00130 00131 /// insertNode - Insert a new node into the graph. Takes 00132 /// ownership of the object. 00133 void insertNode(Tool* T); 00134 00135 /// insertEdge - Insert a new edge into the graph. Takes ownership 00136 /// of the Edge object. 00137 void insertEdge(const std::string& A, Edge* E); 00138 00139 /// Build - Build target(s) from the input file set. Command-line 00140 /// options are passed implicitly as global variables. 00141 int Build(llvm::sys::Path const& TempDir, const LanguageMap& LangMap); 00142 00143 /// Check - Check the compilation graph for common errors like 00144 /// cycles, input/output language mismatch and multiple default 00145 /// edges. Prints error messages and in case it finds any errors. 00146 int Check(); 00147 00148 /// getNode - Return a reference to the node correponding to the 00149 /// given tool name. Throws std::runtime_error. 00150 Node& getNode(const std::string& ToolName); 00151 const Node& getNode(const std::string& ToolName) const; 00152 00153 /// viewGraph - This function is meant for use from the debugger. 00154 /// You can just say 'call G->viewGraph()' and a ghostview window 00155 /// should pop up from the program, displaying the compilation 00156 /// graph. This depends on there being a 'dot' and 'gv' program 00157 /// in your path. 00158 void viewGraph(); 00159 00160 /// writeGraph - Write a compilation-graph.dot file. 00161 void writeGraph(); 00162 00163 // GraphTraits support. 00164 friend NodesIterator GraphBegin(CompilationGraph*); 00165 friend NodesIterator GraphEnd(CompilationGraph*); 00166 00167 private: 00168 // Helper functions. 00169 00170 /// getToolsVector - Return a reference to the list of tool names 00171 /// corresponding to the given language name. Throws 00172 /// std::runtime_error. 00173 const tools_vector_type& getToolsVector(const std::string& LangName) const; 00174 00175 /// PassThroughGraph - Pass the input file through the toolchain 00176 /// starting at StartNode. 00177 void PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode, 00178 const InputLanguagesSet& InLangs, 00179 const llvm::sys::Path& TempDir, 00180 const LanguageMap& LangMap) const; 00181 00182 /// FindToolChain - Find head of the toolchain corresponding to 00183 /// the given file. 00184 const Node* FindToolChain(const llvm::sys::Path& In, 00185 const std::string* ForceLanguage, 00186 InputLanguagesSet& InLangs, 00187 const LanguageMap& LangMap) const; 00188 00189 /// BuildInitial - Traverse the initial parts of the toolchains. 00190 void BuildInitial(InputLanguagesSet& InLangs, 00191 const llvm::sys::Path& TempDir, 00192 const LanguageMap& LangMap); 00193 00194 /// TopologicalSort - Sort the nodes in topological order. 00195 void TopologicalSort(std::vector<const Node*>& Out); 00196 /// TopologicalSortFilterJoinNodes - Call TopologicalSort and 00197 /// filter the resulting list to include only Join nodes. 00198 void TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out); 00199 00200 // Functions used to implement Check(). 00201 00202 /// CheckLanguageNames - Check that output/input language names 00203 /// match for all nodes. 00204 int CheckLanguageNames() const; 00205 /// CheckMultipleDefaultEdges - check that there are no multiple 00206 /// default default edges. 00207 int CheckMultipleDefaultEdges() const; 00208 /// CheckCycles - Check that there are no cycles in the graph. 00209 int CheckCycles(); 00210 00211 }; 00212 00213 // GraphTraits support code. 00214 00215 /// NodesIterator - Auxiliary class needed to implement GraphTraits 00216 /// support. Can be generalised to something like value_iterator 00217 /// for map-like containers. 00218 class NodesIterator : public CompilationGraph::nodes_iterator { 00219 typedef CompilationGraph::nodes_iterator super; 00220 typedef NodesIterator ThisType; 00221 typedef Node* pointer; 00222 typedef Node& reference; 00223 00224 public: 00225 NodesIterator(super I) : super(I) {} 00226 00227 inline reference operator*() const { 00228 return super::operator->()->second; 00229 } 00230 inline pointer operator->() const { 00231 return &super::operator->()->second; 00232 } 00233 }; 00234 00235 inline NodesIterator GraphBegin(CompilationGraph* G) { 00236 return NodesIterator(G->NodesMap.begin()); 00237 } 00238 00239 inline NodesIterator GraphEnd(CompilationGraph* G) { 00240 return NodesIterator(G->NodesMap.end()); 00241 } 00242 00243 00244 /// NodeChildIterator - Another auxiliary class needed by GraphTraits. 00245 class NodeChildIterator : public bidirectional_iterator<Node, ptrdiff_t> { 00246 typedef NodeChildIterator ThisType; 00247 typedef Node::container_type::iterator iterator; 00248 00249 CompilationGraph* OwningGraph; 00250 iterator EdgeIter; 00251 public: 00252 typedef Node* pointer; 00253 typedef Node& reference; 00254 00255 NodeChildIterator(Node* N, iterator I) : 00256 OwningGraph(N->OwningGraph), EdgeIter(I) {} 00257 00258 const ThisType& operator=(const ThisType& I) { 00259 assert(OwningGraph == I.OwningGraph); 00260 EdgeIter = I.EdgeIter; 00261 return *this; 00262 } 00263 00264 inline bool operator==(const ThisType& I) const 00265 { return EdgeIter == I.EdgeIter; } 00266 inline bool operator!=(const ThisType& I) const 00267 { return EdgeIter != I.EdgeIter; } 00268 00269 inline pointer operator*() const { 00270 return &OwningGraph->getNode((*EdgeIter)->ToolName()); 00271 } 00272 inline pointer operator->() const { 00273 return &OwningGraph->getNode((*EdgeIter)->ToolName()); 00274 } 00275 00276 ThisType& operator++() { ++EdgeIter; return *this; } // Preincrement 00277 ThisType operator++(int) { // Postincrement 00278 ThisType tmp = *this; 00279 ++*this; 00280 return tmp; 00281 } 00282 00283 inline ThisType& operator--() { --EdgeIter; return *this; } // Predecrement 00284 inline ThisType operator--(int) { // Postdecrement 00285 ThisType tmp = *this; 00286 --*this; 00287 return tmp; 00288 } 00289 00290 }; 00291 } 00292 00293 namespace llvm { 00294 template <> 00295 struct GraphTraits<llvmc::CompilationGraph*> { 00296 typedef llvmc::CompilationGraph GraphType; 00297 typedef llvmc::Node NodeType; 00298 typedef llvmc::NodeChildIterator ChildIteratorType; 00299 00300 static NodeType* getEntryNode(GraphType* G) { 00301 return &G->getNode("root"); 00302 } 00303 00304 static ChildIteratorType child_begin(NodeType* N) { 00305 return ChildIteratorType(N, N->OutEdges.begin()); 00306 } 00307 static ChildIteratorType child_end(NodeType* N) { 00308 return ChildIteratorType(N, N->OutEdges.end()); 00309 } 00310 00311 typedef llvmc::NodesIterator nodes_iterator; 00312 static nodes_iterator nodes_begin(GraphType *G) { 00313 return GraphBegin(G); 00314 } 00315 static nodes_iterator nodes_end(GraphType *G) { 00316 return GraphEnd(G); 00317 } 00318 }; 00319 00320 } 00321 00322 #endif // LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H