llvm.org GIT mirror llvm / c74bfc9
Add inward edge counters to Nodes; Associate JoinLists with JoinTools. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50738 91177308-0d34-0410-b5e6-96231b3b80d8 Mikhail Glushenkov 11 years ago
4 changed file(s) with 68 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
8585 }
8686
8787 void CompilationGraph::insertNode(Tool* V) {
88 if (!NodesMap.count(V->Name())) {
88 if (NodesMap.count(V->Name()) == 0) {
8989 Node N;
9090 N.OwningGraph = this;
9191 N.ToolPtr = V;
9494 }
9595
9696 void CompilationGraph::insertEdge(const std::string& A, Edge* E) {
97 Node& B = getNode(E->ToolName());
9798 if (A == "root") {
98 const Node& N = getNode(E->ToolName());
99 const std::string& InputLanguage = N.ToolPtr->InputLanguage();
99 const std::string& InputLanguage = B.ToolPtr->InputLanguage();
100100 ToolsMap[InputLanguage].push_back(E->ToolName());
101
102 // Needed to support iteration via GraphTraits.
103101 NodesMap["root"].AddEdge(E);
104102 }
105103 else {
106104 Node& N = getNode(A);
107105 N.AddEdge(E);
108106 }
107 // Increase the inward edge counter.
108 B.IncrInEdges();
109109 }
110110
111111 // Pass input file through the chain until we bump into a Join node or
112112 // a node that says that it is the last.
113 const Tool* CompilationGraph::PassThroughGraph (sys::Path& In,
114 sys::Path Out,
115 const sys::Path& TempDir,
116 PathVector& JoinList) const {
113 const JoinTool*
114 CompilationGraph::PassThroughGraph (sys::Path& In, sys::Path Out,
115 const sys::Path& TempDir) const {
117116 bool Last = false;
118 const Tool* ret = 0;
117 JoinTool* ret = 0;
119118
120119 // Get to the head of the toolchain.
121120 const tools_vector_type& TV = getToolsVector(getLanguage(In));
124123 const Node* N = &getNode(*TV.begin());
125124
126125 while(!Last) {
127 const Tool* CurTool = N->ToolPtr.getPtr();
126 Tool* CurTool = N->ToolPtr.getPtr();
128127
129128 if (CurTool->IsJoin()) {
130 JoinList.push_back(In);
131 ret = CurTool;
129 ret = &dynamic_cast(*CurTool);
130 ret->AddToJoinList(In);
132131 break;
133132 }
134133
160159 return ret;
161160 }
162161
163 // TOFIX: support more interesting graph topologies. We will need to
164 // do topological sorting to process multiple Join nodes correctly.
165162 int CompilationGraph::Build (const sys::Path& TempDir) const {
166 PathVector JoinList;
167 const Tool* JoinTool = 0;
163 const JoinTool* JT = 0;
168164 sys::Path In, Out;
169165
170166 // For each input file
172168 E = InputFilenames.end(); B != E; ++B) {
173169 In = sys::Path(*B);
174170
175 const Tool* NewJoin = PassThroughGraph(In, Out, TempDir, JoinList);
176 if (JoinTool && NewJoin && JoinTool != NewJoin)
171 const JoinTool* NewJoin = PassThroughGraph(In, Out, TempDir);
172 if (JT && NewJoin && JT != NewJoin)
177173 throw std::runtime_error("Graphs with multiple Join nodes"
178174 "are not yet supported!");
179175 else if (NewJoin)
180 JoinTool = NewJoin;
181 }
182
183 if (JoinTool) {
176 JT = NewJoin;
177 }
178
179 if (JT) {
184180 // If the final output name is empty, set it to "a.out"
185181 if (!OutputFilename.empty()) {
186182 Out = sys::Path(OutputFilename);
187183 }
188184 else {
189185 Out = sys::Path("a");
190 Out.appendSuffix(JoinTool->OutputSuffix());
191 }
192
193 if (JoinTool->GenerateAction(JoinList, Out).Execute() != 0)
186 Out.appendSuffix(JT->OutputSuffix());
187 }
188
189 if (JT->GenerateAction(Out).Execute() != 0)
194190 throw std::runtime_error("Tool returned error code!");
195191 }
196192
5454 typedef container_type::iterator iterator;
5555 typedef container_type::const_iterator const_iterator;
5656
57 Node() {}
58 Node(CompilationGraph* G) : OwningGraph(G) {}
59 Node(CompilationGraph* G, Tool* T) : OwningGraph(G), ToolPtr(T) {}
57 Node() : OwningGraph(0), InEdges(0) {}
58 Node(CompilationGraph* G) : OwningGraph(G), InEdges(0) {}
59 Node(CompilationGraph* G, Tool* T) :
60 OwningGraph(G), ToolPtr(T), InEdges(0) {}
6061
6162 bool HasChildren() const { return !OutEdges.empty(); }
6263 const std::string Name() const { return ToolPtr->Name(); }
6364
65 // Iteration.
6466 iterator EdgesBegin() { return OutEdges.begin(); }
6567 const_iterator EdgesBegin() const { return OutEdges.begin(); }
6668 iterator EdgesEnd() { return OutEdges.end(); }
6769 const_iterator EdgesEnd() const { return OutEdges.end(); }
6870
69 // Choose one of the edges based on command-line options.
71 // Choose one of the outward edges based on command-line options.
7072 const Edge* ChooseEdge() const;
7173
72 // Takes ownership of the object.
74 // Add an outward edge. Takes ownership of the Edge object.
7375 void AddEdge(Edge* E)
7476 { OutEdges.push_back(llvm::IntrusiveRefCntPtr(E)); }
77
78 // Inward edge counter. Used by Build() to implement topological
79 // sort.
80 void IncrInEdges() { ++InEdges; }
81 void DecrInEdges() { --InEdges; }
82 bool HasNoInEdges() const { return InEdges == 0; }
7583
7684 // Needed to implement NodeChildIterator/GraphTraits
7785 CompilationGraph* OwningGraph;
7987 llvm::IntrusiveRefCntPtr ToolPtr;
8088 // Links to children.
8189 container_type OutEdges;
90 // Number of parents.
91 unsigned InEdges;
8292 };
8393
8494 class NodesIterator;
104114 void insertNode(Tool* T);
105115
106116 // insertEdge - Insert a new edge into the graph. Takes ownership
107 // of the object.
117 // of the Edge object.
108118 void insertEdge(const std::string& A, Edge* E);
109119
110120 // Build - Build target(s) from the input file set. Command-line
142152 const tools_vector_type& getToolsVector(const std::string& LangName) const;
143153
144154 // Pass the input file through the toolchain.
145 const Tool* PassThroughGraph (llvm::sys::Path& In, llvm::sys::Path Out,
146 const llvm::sys::Path& TempDir,
147 PathVector& JoinList) const;
155 const JoinTool* PassThroughGraph (llvm::sys::Path& In, llvm::sys::Path Out,
156 const llvm::sys::Path& TempDir) const;
148157
149158 };
150159
2727
2828 class Tool : public llvm::RefCountedBaseVPTR {
2929 public:
30 virtual Action GenerateAction (PathVector const& inFiles,
31 llvm::sys::Path const& outFile) const = 0;
3230
33 virtual Action GenerateAction (llvm::sys::Path const& inFile,
34 llvm::sys::Path const& outFile) const = 0;
31 virtual ~Tool() {}
32
33 virtual Action GenerateAction (const PathVector& inFiles,
34 const llvm::sys::Path& outFile) const = 0;
35
36 virtual Action GenerateAction (const llvm::sys::Path& inFile,
37 const llvm::sys::Path& outFile) const = 0;
3538
3639 virtual const char* Name() const = 0;
3740 virtual const char* InputLanguage() const = 0;
4649 // TOFIX: find a better name
4750 static void UnpackValues (std::string const& from,
4851 std::vector& to);
52 };
4953
50 virtual ~Tool()
51 {}
54 // Join tools have an input file list associated with them.
55 class JoinTool : public Tool {
56 public:
57 void AddToJoinList(const llvm::sys::Path& P) { JoinList.push_back(P); }
58 void ClearJoinList() { JoinList.clear(); }
59
60 Action GenerateAction(const llvm::sys::Path& outFile) const
61 { return GenerateAction(JoinList, outFile); }
62 // We shouldn't shadow GenerateAction from the base class.
63 using Tool::GenerateAction;
64
65 private:
66 PathVector JoinList;
5267 };
5368
5469 }
781781 return;
782782
783783 // Header
784 O << "class " << P.Name << " : public Tool {\n"
785 << "public:\n";
784 O << "class " << P.Name << " : public ";
785 if (P.isJoin())
786 O << "JoinTool";
787 else
788 O << "Tool";
789 O << "{\npublic:\n";
786790
787791 EmitNameMethod(P, O);
788792 EmitInOutLanguageMethods(P, O);