blob: 85210dc499c3817cc6f2096538eb3a821d2e6c25 [file] [log] [blame]
Mikhail Glushenkovb90cd832008-05-06 16:34:12 +00001//===--- 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 Glushenkov0d08db02008-05-06 16:35:25 +000020#include "llvm/ADT/GraphTraits.h"
Mikhail Glushenkov0a174932008-05-06 16:36:06 +000021#include "llvm/ADT/IntrusiveRefCntPtr.h"
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +000022#include "llvm/ADT/iterator"
23#include "llvm/ADT/SmallVector.h"
Mikhail Glushenkovb90cd832008-05-06 16:34:12 +000024#include "llvm/ADT/StringMap.h"
25#include "llvm/System/Path.h"
26
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +000027#include <string>
28
Mikhail Glushenkovb90cd832008-05-06 16:34:12 +000029namespace llvmcc {
30
Mikhail Glushenkov0a174932008-05-06 16:36:06 +000031 class Edge : public llvm::RefCountedBaseVPTR<Edge> {
32 public:
33 Edge(const std::string& T) : ToolName_(T) {}
34 virtual ~Edge() {};
35
36 const std::string& ToolName() const { return ToolName_; }
37 virtual bool isEnabled() const = 0;
38 virtual bool isDefault() const = 0;
39 private:
40 std::string ToolName_;
41 };
42
43 class DefaultEdge : public Edge {
44 public:
45 DefaultEdge(const std::string& T) : Edge(T) {}
46 bool isEnabled() const { return true;}
47 bool isDefault() const { return true;}
48 };
Mikhail Glushenkovb90cd832008-05-06 16:34:12 +000049
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +000050 struct Node {
Mikhail Glushenkov0a174932008-05-06 16:36:06 +000051 typedef llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> container_type;
52 typedef container_type::iterator iterator;
53 typedef container_type::const_iterator const_iterator;
Mikhail Glushenkovb90cd832008-05-06 16:34:12 +000054
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +000055 Node() {}
56 Node(CompilationGraph* G) : OwningGraph(G) {}
57 Node(CompilationGraph* G, Tool* T) : OwningGraph(G), ToolPtr(T) {}
58
Mikhail Glushenkov0a174932008-05-06 16:36:06 +000059 bool HasChildren() const { return OutEdges.empty(); }
60
61 iterator EdgesBegin() { return OutEdges.begin(); }
62 const_iterator EdgesBegin() const { return OutEdges.begin(); }
63 iterator EdgesEnd() { return OutEdges.end(); }
64 const_iterator EdgesEnd() const { return OutEdges.end(); }
65
66 // E is a new-allocated pointer.
67 void AddEdge(Edge* E)
68 { OutEdges.push_back(llvm::IntrusiveRefCntPtr<Edge>(E)); }
69
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +000070 // Needed to implement NodeChildIterator/GraphTraits
71 CompilationGraph* OwningGraph;
72 // The corresponding Tool.
73 llvm::IntrusiveRefCntPtr<Tool> ToolPtr;
74 // Links to children.
Mikhail Glushenkov0a174932008-05-06 16:36:06 +000075 container_type OutEdges;
Mikhail Glushenkovb90cd832008-05-06 16:34:12 +000076 };
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +000077
Mikhail Glushenkov0a174932008-05-06 16:36:06 +000078 class NodesIterator;
79
80 class CompilationGraph {
81 typedef llvm::SmallVector<std::string, 3> tools_vector_type;
82 typedef llvm::StringMap<tools_vector_type> tools_map_type;
83 typedef llvm::StringMap<Node> nodes_map_type;
84
85 // Map from file extensions to language names.
86 LanguageMap ExtsToLangs;
87 // Map from language names to lists of tool names.
88 tools_map_type ToolsMap;
89 // Map from tool names to Tool objects.
90 nodes_map_type NodesMap;
91
92 public:
93
94 CompilationGraph();
95
96 // insertVertex - insert a new node into the graph.
97 void insertNode(Tool* T);
98
99 // insertEdge - Insert a new edge into the graph. This function
100 // assumes that both A and B have been already inserted.
101 void insertEdge(const std::string& A, const std::string& B);
102
103 // Build - Build the target(s) from the set of the input
104 // files. Command-line options are passed implicitly as global
105 // variables.
106 int Build(llvm::sys::Path const& tempDir) const;
107
108 // Return a reference to the node correponding to the given tool
109 // name. Throws std::runtime_error.
110 Node& getNode(const std::string& ToolName);
111 const Node& getNode(const std::string& ToolName) const;
112
113 // viewGraph - This function is meant for use from the debugger.
114 // You can just say 'call G->viewGraph()' and a ghostview window
115 // should pop up from the program, displaying the compilation
116 // graph. This depends on there being a 'dot' and 'gv' program
117 // in your path.
118 void viewGraph();
119
120 // Write a CompilationGraph.dot file.
121 void writeGraph();
122
123 // GraphTraits support
124 friend NodesIterator GraphBegin(CompilationGraph*);
125 friend NodesIterator GraphEnd(CompilationGraph*);
126 friend void PopulateCompilationGraph(CompilationGraph&);
127
128 private:
129 // Helper functions.
130
131 // Find out which language corresponds to the suffix of this file.
132 const std::string& getLanguage(const llvm::sys::Path& File) const;
133
134 // Return a reference to the list of tool names corresponding to
135 // the given language name. Throws std::runtime_error.
136 const tools_vector_type& getToolsVector(const std::string& LangName) const;
137 };
138
139 /// GraphTraits support code.
140
141 // Auxiliary class needed to implement GraphTraits support. Can be
142 // generalised to something like value_iterator for map-like
143 // containers.
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000144 class NodesIterator : public llvm::StringMap<Node>::iterator {
145 typedef llvm::StringMap<Node>::iterator super;
146 typedef NodesIterator ThisType;
147 typedef Node* pointer;
148 typedef Node& reference;
149
150 public:
151 NodesIterator(super I) : super(I) {}
152
153 inline reference operator*() const {
154 return super::operator->()->second;
155 }
156 inline pointer operator->() const {
157 return &super::operator->()->second;
158 }
159 };
160
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000161 inline NodesIterator GraphBegin(CompilationGraph* G) {
162 return NodesIterator(G->NodesMap.begin());
163 }
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000164
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000165 inline NodesIterator GraphEnd(CompilationGraph* G) {
166 return NodesIterator(G->NodesMap.end());
167 }
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000168
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000169
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000170 // Another auxiliary class needed by GraphTraits.
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000171 class NodeChildIterator : public bidirectional_iterator<Node, ptrdiff_t> {
172 typedef NodeChildIterator ThisType;
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000173 typedef Node::container_type::iterator iterator;
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000174
175 CompilationGraph* OwningGraph;
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000176 iterator EdgeIter;
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000177 public:
178 typedef Node* pointer;
179 typedef Node& reference;
180
181 NodeChildIterator(Node* N, iterator I) :
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000182 OwningGraph(N->OwningGraph), EdgeIter(I) {}
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000183
184 const ThisType& operator=(const ThisType& I) {
185 assert(OwningGraph == I.OwningGraph);
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000186 EdgeIter = I.EdgeIter;
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000187 return *this;
188 }
189
190 inline bool operator==(const ThisType& I) const
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000191 { return EdgeIter == I.EdgeIter; }
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000192 inline bool operator!=(const ThisType& I) const
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000193 { return EdgeIter != I.EdgeIter; }
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000194
195 inline pointer operator*() const {
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000196 return &OwningGraph->getNode((*EdgeIter)->ToolName());
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000197 }
198 inline pointer operator->() const {
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000199 return &OwningGraph->getNode((*EdgeIter)->ToolName());
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000200 }
201
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000202 ThisType& operator++() { ++EdgeIter; return *this; } // Preincrement
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000203 ThisType operator++(int) { // Postincrement
204 ThisType tmp = *this;
205 ++*this;
206 return tmp;
207 }
208
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000209 inline ThisType& operator--() { --EdgeIter; return *this; } // Predecrement
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000210 inline ThisType operator--(int) { // Postdecrement
211 ThisType tmp = *this;
212 --*this;
213 return tmp;
214 }
215
216 };
217}
218
219namespace llvm {
220 template <>
221 struct GraphTraits<llvmcc::CompilationGraph*> {
222 typedef llvmcc::CompilationGraph GraphType;
223 typedef llvmcc::Node NodeType;
224 typedef llvmcc::NodeChildIterator ChildIteratorType;
225
226 static NodeType* getEntryNode(GraphType* G) {
227 return &G->getNode("root");
228 }
229
230 static ChildIteratorType child_begin(NodeType* N) {
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000231 return ChildIteratorType(N, N->OutEdges.begin());
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000232 }
233 static ChildIteratorType child_end(NodeType* N) {
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000234 return ChildIteratorType(N, N->OutEdges.end());
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000235 }
236
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000237 typedef llvmcc::NodesIterator nodes_iterator;
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000238 static nodes_iterator nodes_begin(GraphType *G) {
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000239 return GraphBegin(G);
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000240 }
241 static nodes_iterator nodes_end(GraphType *G) {
Mikhail Glushenkov0a174932008-05-06 16:36:06 +0000242 return GraphEnd(G);
Mikhail Glushenkov0d08db02008-05-06 16:35:25 +0000243 }
244 };
245
Mikhail Glushenkovb90cd832008-05-06 16:34:12 +0000246}
247
248#endif // LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H