llvm.org GIT mirror llvm / 0260658
Add TopologicalSort method to CompilationGraph. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50743 91177308-0d34-0410-b5e6-96231b3b80d8 Mikhail Glushenkov 12 years ago
4 changed file(s) with 79 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
1616 #include "llvm/Support/DOTGraphTraits.h"
1717 #include "llvm/Support/GraphWriter.h"
1818
19 #include
20 #include
21 #include
22 #include
1923 #include
2024
2125 using namespace llvm;
165169 return ret;
166170 }
167171
168 int CompilationGraph::Build (const sys::Path& TempDir) const {
169 const JoinTool* JT = 0;
172 // Sort the nodes in topological order.
173 void CompilationGraph::TopologicalSort(std::vector& Out) {
174 std::queue Q;
175 Q.push(&getNode("root"));
176
177 while (!Q.empty()) {
178 const Node* A = Q.front();
179 Q.pop();
180 Out.push_back(A);
181 for (Node::const_iterator EB = A->EdgesBegin(), EE = A->EdgesEnd();
182 EB != EE; ++EB) {
183 Node* B = &getNode((*EB)->ToolName());
184 B->DecrInEdges();
185 if (B->HasNoInEdges())
186 Q.push(B);
187 }
188 }
189 }
190
191 namespace {
192 bool NotJoinNode(const Node* N) {
193 return N->ToolPtr ? !N->ToolPtr->IsJoin() : true;
194 }
195 }
196
197 // Call TopologicalSort and filter the resulting list to include
198 // only Join nodes.
199 void CompilationGraph::
200 TopologicalSortFilterJoinNodes(std::vector& Out) {
201 std::vector TopSorted;
202 TopologicalSort(TopSorted);
203 std::remove_copy_if(TopSorted.begin(), TopSorted.end(),
204 std::back_inserter(Out), NotJoinNode);
205 }
206
207 // Find head of the toolchain corresponding to the given file.
208 const Node* CompilationGraph::FindToolChain(const sys::Path& In) const {
209 const std::string& InLanguage = getLanguage(In);
210 const tools_vector_type& TV = getToolsVector(InLanguage);
211 if (TV.empty())
212 throw std::runtime_error("No toolchain corresponding to language"
213 + InLanguage + " found!");
214 return &getNode(ChooseEdge(TV)->ToolName());
215 }
216
217 int CompilationGraph::Build (const sys::Path& TempDir) {
170218
171219 // For each input file:
172220 for (cl::list::const_iterator B = InputFilenames.begin(),
173221 E = InputFilenames.end(); B != E; ++B) {
174222 sys::Path In = sys::Path(*B);
175223
176 // Get to the head of the toolchain.
177 const std::string& InLanguage = getLanguage(In);
178 const tools_vector_type& TV = getToolsVector(InLanguage);
179 if (TV.empty())
180 throw std::runtime_error("No toolchain corresponding to language"
181 + InLanguage + " found!");
182 const Node* N = &getNode(ChooseEdge(TV)->ToolName());
183
184 // Pass it through the chain starting at head.
185 const JoinTool* NewJoin = PassThroughGraph(In, N, TempDir);
186 if (JT && NewJoin && JT != NewJoin)
187 throw std::runtime_error("Graphs with multiple Join nodes"
188 "are not yet supported!");
189 else if (NewJoin)
190 JT = NewJoin;
191 }
224 // Find the toolchain corresponding to this file.
225 const Node* N = FindToolChain(In);
226 // Pass file through the chain starting at head.
227 PassThroughGraph(In, N, TempDir);
228 }
229
230 std::vector JTV;
231 TopologicalSortFilterJoinNodes(JTV);
192232
193233 // For all join nodes in topological order:
194 // TOFIX: implement.
195 if (JT) {
196 sys::Path Out;
197 // If the final output name is empty, set it to "a.out"
198 if (!OutputFilename.empty()) {
199 Out = sys::Path(OutputFilename);
200 }
201 else {
202 Out = sys::Path("a");
203 Out.appendSuffix(JT->OutputSuffix());
204 }
205
206 if (JT->GenerateAction(Out).Execute() != 0)
207 throw std::runtime_error("Tool returned error code!");
234 for (std::vector::iterator B = JTV.begin(), E = JTV.end();
235 B != E; ++B) {
208236 }
209237
210238 return 0;
6060 OwningGraph(G), ToolPtr(T), InEdges(0) {}
6161
6262 bool HasChildren() const { return !OutEdges.empty(); }
63 const std::string Name() const { return ToolPtr->Name(); }
63 const std::string Name() const
64 { return ToolPtr ? ToolPtr->Name() : "root"; }
6465
6566 // Iteration.
6667 iterator EdgesBegin() { return OutEdges.begin(); }
7475
7576 // Inward edge counter. Used by Build() to implement topological
7677 // sort.
78 // TOTHINK: Move the counter back into Tool classes? Makes us more
79 // const-correct.
7780 void IncrInEdges() { ++InEdges; }
7881 void DecrInEdges() { --InEdges; }
7982 bool HasNoInEdges() const { return InEdges == 0; }
8184 // Needed to implement NodeChildIterator/GraphTraits
8285 CompilationGraph* OwningGraph;
8386 // The corresponding Tool.
87 // WARNING: For the root node, ToolPtr is NULL.
8488 llvm::IntrusiveRefCntPtr ToolPtr;
8589 // Links to children.
8690 container_type OutEdges;
87 // Number of parents.
91 // Number of parents. Used for topological sorting.
8892 unsigned InEdges;
8993 };
9094
9195 class NodesIterator;
9296
97 // The compilation graph itself.
9398 class CompilationGraph {
9499 // Main data structure.
95100 typedef llvm::StringMap nodes_map_type;
120125
121126 // Build - Build target(s) from the input file set. Command-line
122127 // options are passed implicitly as global variables.
123 int Build(llvm::sys::Path const& tempDir) const;
128 int Build(llvm::sys::Path const& tempDir);
124129
125130 // Return a reference to the node correponding to the given tool
126131 // name. Throws std::runtime_error.
157162 const Node* StartNode,
158163 const llvm::sys::Path& TempDir) const;
159164
165 // Find head of the toolchain corresponding to the given file.
166 const Node* FindToolChain(const llvm::sys::Path& In) const;
167
168 // Sort the nodes in topological order.
169 void TopologicalSort(std::vector& Out);
170 // Call TopologicalSort and filter the resulting list to include
171 // only Join nodes.
172 void TopologicalSortFilterJoinNodes(std::vector& Out);
160173 };
161174
162175 /// GraphTraits support code.
3838 [(in_language "llvm-bitcode"),
3939 (out_language "llvm-bitcode"),
4040 (switch_option "opt", (help "Enable opt")),
41 //(parameter_option "O", (help "Test Parameter")),
42 //(prefix_list_option "P", (help "Test Parameter List")),
4341 (output_suffix "bc"),
4442 (cmd_line "opt $INFILE -o $OUTFILE")
4543 ]>;
4444 cl::Hidden);
4545
4646 namespace {
47 int BuildTargets(const CompilationGraph& graph) {
47 int BuildTargets(CompilationGraph& graph) {
4848 int ret;
4949 sys::Path tempDir(sys::Path::GetTemporaryDirectory());
5050
6666 CompilationGraph graph;
6767
6868 cl::ParseCommandLineOptions(argc, argv,
69 "LLVM Compiler Driver(Work In Progress)");
69 "LLVM Compiler Driver (Work In Progress)");
7070 PopulateCompilationGraph(graph);
7171
7272 if (WriteGraph) {
7878 graph.viewGraph();
7979 return 0;
8080 }
81
8182
8283 if (InputFilenames.empty()) {
8384 std::cerr << "No input files.\n";