forked from OSchip/llvm-project
Add TopologicalSort method to CompilationGraph.
llvm-svn: 50743
This commit is contained in:
parent
af932f0d96
commit
7701512231
|
@ -17,6 +17,10 @@
|
|||
#include "llvm/Support/DOTGraphTraits.h"
|
||||
#include "llvm/Support/GraphWriter.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <queue>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace llvm;
|
||||
|
@ -166,46 +170,70 @@ CompilationGraph::PassThroughGraph (sys::Path& In,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int CompilationGraph::Build (const sys::Path& TempDir) const {
|
||||
const JoinTool* JT = 0;
|
||||
// Sort the nodes in topological order.
|
||||
void CompilationGraph::TopologicalSort(std::vector<const Node*>& Out) {
|
||||
std::queue<const Node*> Q;
|
||||
Q.push(&getNode("root"));
|
||||
|
||||
while (!Q.empty()) {
|
||||
const Node* A = Q.front();
|
||||
Q.pop();
|
||||
Out.push_back(A);
|
||||
for (Node::const_iterator EB = A->EdgesBegin(), EE = A->EdgesEnd();
|
||||
EB != EE; ++EB) {
|
||||
Node* B = &getNode((*EB)->ToolName());
|
||||
B->DecrInEdges();
|
||||
if (B->HasNoInEdges())
|
||||
Q.push(B);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool NotJoinNode(const Node* N) {
|
||||
return N->ToolPtr ? !N->ToolPtr->IsJoin() : true;
|
||||
}
|
||||
}
|
||||
|
||||
// Call TopologicalSort and filter the resulting list to include
|
||||
// only Join nodes.
|
||||
void CompilationGraph::
|
||||
TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out) {
|
||||
std::vector<const Node*> TopSorted;
|
||||
TopologicalSort(TopSorted);
|
||||
std::remove_copy_if(TopSorted.begin(), TopSorted.end(),
|
||||
std::back_inserter(Out), NotJoinNode);
|
||||
}
|
||||
|
||||
// Find head of the toolchain corresponding to the given file.
|
||||
const Node* CompilationGraph::FindToolChain(const sys::Path& In) const {
|
||||
const std::string& InLanguage = getLanguage(In);
|
||||
const tools_vector_type& TV = getToolsVector(InLanguage);
|
||||
if (TV.empty())
|
||||
throw std::runtime_error("No toolchain corresponding to language"
|
||||
+ InLanguage + " found!");
|
||||
return &getNode(ChooseEdge(TV)->ToolName());
|
||||
}
|
||||
|
||||
int CompilationGraph::Build (const sys::Path& TempDir) {
|
||||
|
||||
// For each input file:
|
||||
for (cl::list<std::string>::const_iterator B = InputFilenames.begin(),
|
||||
E = InputFilenames.end(); B != E; ++B) {
|
||||
sys::Path In = sys::Path(*B);
|
||||
|
||||
// Get to the head of the toolchain.
|
||||
const std::string& InLanguage = getLanguage(In);
|
||||
const tools_vector_type& TV = getToolsVector(InLanguage);
|
||||
if (TV.empty())
|
||||
throw std::runtime_error("No toolchain corresponding to language"
|
||||
+ InLanguage + " found!");
|
||||
const Node* N = &getNode(ChooseEdge(TV)->ToolName());
|
||||
|
||||
// Pass it through the chain starting at head.
|
||||
const JoinTool* NewJoin = PassThroughGraph(In, N, TempDir);
|
||||
if (JT && NewJoin && JT != NewJoin)
|
||||
throw std::runtime_error("Graphs with multiple Join nodes"
|
||||
"are not yet supported!");
|
||||
else if (NewJoin)
|
||||
JT = NewJoin;
|
||||
// Find the toolchain corresponding to this file.
|
||||
const Node* N = FindToolChain(In);
|
||||
// Pass file through the chain starting at head.
|
||||
PassThroughGraph(In, N, TempDir);
|
||||
}
|
||||
|
||||
// For all join nodes in topological order:
|
||||
// TOFIX: implement.
|
||||
if (JT) {
|
||||
sys::Path Out;
|
||||
// If the final output name is empty, set it to "a.out"
|
||||
if (!OutputFilename.empty()) {
|
||||
Out = sys::Path(OutputFilename);
|
||||
}
|
||||
else {
|
||||
Out = sys::Path("a");
|
||||
Out.appendSuffix(JT->OutputSuffix());
|
||||
}
|
||||
std::vector<const Node*> JTV;
|
||||
TopologicalSortFilterJoinNodes(JTV);
|
||||
|
||||
if (JT->GenerateAction(Out).Execute() != 0)
|
||||
throw std::runtime_error("Tool returned error code!");
|
||||
// For all join nodes in topological order:
|
||||
for (std::vector<const Node*>::iterator B = JTV.begin(), E = JTV.end();
|
||||
B != E; ++B) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -61,7 +61,8 @@ namespace llvmcc {
|
|||
OwningGraph(G), ToolPtr(T), InEdges(0) {}
|
||||
|
||||
bool HasChildren() const { return !OutEdges.empty(); }
|
||||
const std::string Name() const { return ToolPtr->Name(); }
|
||||
const std::string Name() const
|
||||
{ return ToolPtr ? ToolPtr->Name() : "root"; }
|
||||
|
||||
// Iteration.
|
||||
iterator EdgesBegin() { return OutEdges.begin(); }
|
||||
|
@ -75,6 +76,8 @@ namespace llvmcc {
|
|||
|
||||
// Inward edge counter. Used by Build() to implement topological
|
||||
// sort.
|
||||
// TOTHINK: Move the counter back into Tool classes? Makes us more
|
||||
// const-correct.
|
||||
void IncrInEdges() { ++InEdges; }
|
||||
void DecrInEdges() { --InEdges; }
|
||||
bool HasNoInEdges() const { return InEdges == 0; }
|
||||
|
@ -82,15 +85,17 @@ namespace llvmcc {
|
|||
// Needed to implement NodeChildIterator/GraphTraits
|
||||
CompilationGraph* OwningGraph;
|
||||
// The corresponding Tool.
|
||||
// WARNING: For the root node, ToolPtr is NULL.
|
||||
llvm::IntrusiveRefCntPtr<Tool> ToolPtr;
|
||||
// Links to children.
|
||||
container_type OutEdges;
|
||||
// Number of parents.
|
||||
// Number of parents. Used for topological sorting.
|
||||
unsigned InEdges;
|
||||
};
|
||||
|
||||
class NodesIterator;
|
||||
|
||||
// The compilation graph itself.
|
||||
class CompilationGraph {
|
||||
// Main data structure.
|
||||
typedef llvm::StringMap<Node> nodes_map_type;
|
||||
|
@ -121,7 +126,7 @@ namespace llvmcc {
|
|||
|
||||
// Build - Build target(s) from the input file set. Command-line
|
||||
// options are passed implicitly as global variables.
|
||||
int Build(llvm::sys::Path const& tempDir) const;
|
||||
int Build(llvm::sys::Path const& tempDir);
|
||||
|
||||
// Return a reference to the node correponding to the given tool
|
||||
// name. Throws std::runtime_error.
|
||||
|
@ -158,6 +163,14 @@ namespace llvmcc {
|
|||
const Node* StartNode,
|
||||
const llvm::sys::Path& TempDir) const;
|
||||
|
||||
// Find head of the toolchain corresponding to the given file.
|
||||
const Node* FindToolChain(const llvm::sys::Path& In) const;
|
||||
|
||||
// Sort the nodes in topological order.
|
||||
void TopologicalSort(std::vector<const Node*>& Out);
|
||||
// Call TopologicalSort and filter the resulting list to include
|
||||
// only Join nodes.
|
||||
void TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out);
|
||||
};
|
||||
|
||||
/// GraphTraits support code.
|
||||
|
|
|
@ -39,8 +39,6 @@ def opt : Tool<
|
|||
[(in_language "llvm-bitcode"),
|
||||
(out_language "llvm-bitcode"),
|
||||
(switch_option "opt", (help "Enable opt")),
|
||||
//(parameter_option "O", (help "Test Parameter")),
|
||||
//(prefix_list_option "P", (help "Test Parameter List")),
|
||||
(output_suffix "bc"),
|
||||
(cmd_line "opt $INFILE -o $OUTFILE")
|
||||
]>;
|
||||
|
|
|
@ -45,7 +45,7 @@ cl::opt<bool> ViewGraph("view-graph",
|
|||
cl::Hidden);
|
||||
|
||||
namespace {
|
||||
int BuildTargets(const CompilationGraph& graph) {
|
||||
int BuildTargets(CompilationGraph& graph) {
|
||||
int ret;
|
||||
sys::Path tempDir(sys::Path::GetTemporaryDirectory());
|
||||
|
||||
|
@ -67,7 +67,7 @@ int main(int argc, char** argv) {
|
|||
CompilationGraph graph;
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv,
|
||||
"LLVM Compiler Driver(Work In Progress)");
|
||||
"LLVM Compiler Driver (Work In Progress)");
|
||||
PopulateCompilationGraph(graph);
|
||||
|
||||
if (WriteGraph) {
|
||||
|
@ -80,6 +80,7 @@ int main(int argc, char** argv) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (InputFilenames.empty()) {
|
||||
std::cerr << "No input files.\n";
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue