From: Mikhail Glushenkov Date: Tue, 6 May 2008 17:26:53 +0000 (+0000) Subject: Add inward edge counters to Nodes; Associate JoinLists with JoinTools. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=c74bfc946d9d093e299b959be956bde7ceb74cb1;p=oota-llvm.git 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 --- diff --git a/tools/llvmc2/CompilationGraph.cpp b/tools/llvmc2/CompilationGraph.cpp index c0c849be232..2dd88128272 100644 --- a/tools/llvmc2/CompilationGraph.cpp +++ b/tools/llvmc2/CompilationGraph.cpp @@ -86,7 +86,7 @@ CompilationGraph::getToolsVector(const std::string& LangName) const } void CompilationGraph::insertNode(Tool* V) { - if (!NodesMap.count(V->Name())) { + if (NodesMap.count(V->Name()) == 0) { Node N; N.OwningGraph = this; N.ToolPtr = V; @@ -95,28 +95,27 @@ void CompilationGraph::insertNode(Tool* V) { } void CompilationGraph::insertEdge(const std::string& A, Edge* E) { + Node& B = getNode(E->ToolName()); if (A == "root") { - const Node& N = getNode(E->ToolName()); - const std::string& InputLanguage = N.ToolPtr->InputLanguage(); + const std::string& InputLanguage = B.ToolPtr->InputLanguage(); ToolsMap[InputLanguage].push_back(E->ToolName()); - - // Needed to support iteration via GraphTraits. NodesMap["root"].AddEdge(E); } else { Node& N = getNode(A); N.AddEdge(E); } + // Increase the inward edge counter. + B.IncrInEdges(); } // Pass input file through the chain until we bump into a Join node or // a node that says that it is the last. -const Tool* CompilationGraph::PassThroughGraph (sys::Path& In, - sys::Path Out, - const sys::Path& TempDir, - PathVector& JoinList) const { +const JoinTool* +CompilationGraph::PassThroughGraph (sys::Path& In, sys::Path Out, + const sys::Path& TempDir) const { bool Last = false; - const Tool* ret = 0; + JoinTool* ret = 0; // Get to the head of the toolchain. const tools_vector_type& TV = getToolsVector(getLanguage(In)); @@ -125,11 +124,11 @@ const Tool* CompilationGraph::PassThroughGraph (sys::Path& In, const Node* N = &getNode(*TV.begin()); while(!Last) { - const Tool* CurTool = N->ToolPtr.getPtr(); + Tool* CurTool = N->ToolPtr.getPtr(); if (CurTool->IsJoin()) { - JoinList.push_back(In); - ret = CurTool; + ret = &dynamic_cast(*CurTool); + ret->AddToJoinList(In); break; } @@ -161,11 +160,8 @@ const Tool* CompilationGraph::PassThroughGraph (sys::Path& In, return ret; } -// TOFIX: support more interesting graph topologies. We will need to -// do topological sorting to process multiple Join nodes correctly. int CompilationGraph::Build (const sys::Path& TempDir) const { - PathVector JoinList; - const Tool* JoinTool = 0; + const JoinTool* JT = 0; sys::Path In, Out; // For each input file @@ -173,25 +169,25 @@ int CompilationGraph::Build (const sys::Path& TempDir) const { E = InputFilenames.end(); B != E; ++B) { In = sys::Path(*B); - const Tool* NewJoin = PassThroughGraph(In, Out, TempDir, JoinList); - if (JoinTool && NewJoin && JoinTool != NewJoin) + const JoinTool* NewJoin = PassThroughGraph(In, Out, TempDir); + if (JT && NewJoin && JT != NewJoin) throw std::runtime_error("Graphs with multiple Join nodes" "are not yet supported!"); else if (NewJoin) - JoinTool = NewJoin; + JT = NewJoin; } - if (JoinTool) { + if (JT) { // 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(JoinTool->OutputSuffix()); + Out.appendSuffix(JT->OutputSuffix()); } - if (JoinTool->GenerateAction(JoinList, Out).Execute() != 0) + if (JT->GenerateAction(Out).Execute() != 0) throw std::runtime_error("Tool returned error code!"); } diff --git a/tools/llvmc2/CompilationGraph.h b/tools/llvmc2/CompilationGraph.h index bddd8bdf3a1..bf46fa5978f 100644 --- a/tools/llvmc2/CompilationGraph.h +++ b/tools/llvmc2/CompilationGraph.h @@ -55,31 +55,41 @@ namespace llvmcc { typedef container_type::iterator iterator; typedef container_type::const_iterator const_iterator; - Node() {} - Node(CompilationGraph* G) : OwningGraph(G) {} - Node(CompilationGraph* G, Tool* T) : OwningGraph(G), ToolPtr(T) {} + Node() : OwningGraph(0), InEdges(0) {} + Node(CompilationGraph* G) : OwningGraph(G), InEdges(0) {} + Node(CompilationGraph* G, Tool* T) : + OwningGraph(G), ToolPtr(T), InEdges(0) {} bool HasChildren() const { return !OutEdges.empty(); } const std::string Name() const { return ToolPtr->Name(); } + // Iteration. iterator EdgesBegin() { return OutEdges.begin(); } const_iterator EdgesBegin() const { return OutEdges.begin(); } iterator EdgesEnd() { return OutEdges.end(); } const_iterator EdgesEnd() const { return OutEdges.end(); } - // Choose one of the edges based on command-line options. + // Choose one of the outward edges based on command-line options. const Edge* ChooseEdge() const; - // Takes ownership of the object. + // Add an outward edge. Takes ownership of the Edge object. void AddEdge(Edge* E) { OutEdges.push_back(llvm::IntrusiveRefCntPtr(E)); } + // Inward edge counter. Used by Build() to implement topological + // sort. + void IncrInEdges() { ++InEdges; } + void DecrInEdges() { --InEdges; } + bool HasNoInEdges() const { return InEdges == 0; } + // Needed to implement NodeChildIterator/GraphTraits CompilationGraph* OwningGraph; // The corresponding Tool. llvm::IntrusiveRefCntPtr ToolPtr; // Links to children. container_type OutEdges; + // Number of parents. + unsigned InEdges; }; class NodesIterator; @@ -105,7 +115,7 @@ namespace llvmcc { void insertNode(Tool* T); // insertEdge - Insert a new edge into the graph. Takes ownership - // of the object. + // of the Edge object. void insertEdge(const std::string& A, Edge* E); // Build - Build target(s) from the input file set. Command-line @@ -143,9 +153,8 @@ namespace llvmcc { const tools_vector_type& getToolsVector(const std::string& LangName) const; // Pass the input file through the toolchain. - const Tool* PassThroughGraph (llvm::sys::Path& In, llvm::sys::Path Out, - const llvm::sys::Path& TempDir, - PathVector& JoinList) const; + const JoinTool* PassThroughGraph (llvm::sys::Path& In, llvm::sys::Path Out, + const llvm::sys::Path& TempDir) const; }; diff --git a/tools/llvmc2/Tool.h b/tools/llvmc2/Tool.h index 0d907dd83a8..5136468a43e 100644 --- a/tools/llvmc2/Tool.h +++ b/tools/llvmc2/Tool.h @@ -28,11 +28,14 @@ namespace llvmcc { class Tool : public llvm::RefCountedBaseVPTR { public: - virtual Action GenerateAction (PathVector const& inFiles, - llvm::sys::Path const& outFile) const = 0; - virtual Action GenerateAction (llvm::sys::Path const& inFile, - llvm::sys::Path const& outFile) const = 0; + virtual ~Tool() {} + + virtual Action GenerateAction (const PathVector& inFiles, + const llvm::sys::Path& outFile) const = 0; + + virtual Action GenerateAction (const llvm::sys::Path& inFile, + const llvm::sys::Path& outFile) const = 0; virtual const char* Name() const = 0; virtual const char* InputLanguage() const = 0; @@ -47,9 +50,21 @@ namespace llvmcc { // TOFIX: find a better name static void UnpackValues (std::string const& from, std::vector& to); + }; + + // Join tools have an input file list associated with them. + class JoinTool : public Tool { + public: + void AddToJoinList(const llvm::sys::Path& P) { JoinList.push_back(P); } + void ClearJoinList() { JoinList.clear(); } + + Action GenerateAction(const llvm::sys::Path& outFile) const + { return GenerateAction(JoinList, outFile); } + // We shouldn't shadow GenerateAction from the base class. + using Tool::GenerateAction; - virtual ~Tool() - {} + private: + PathVector JoinList; }; } diff --git a/utils/TableGen/LLVMCCConfigurationEmitter.cpp b/utils/TableGen/LLVMCCConfigurationEmitter.cpp index fe8e50695ca..b0ecab35b7e 100644 --- a/utils/TableGen/LLVMCCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCCConfigurationEmitter.cpp @@ -782,8 +782,12 @@ void EmitToolClassDefinition (const ToolProperties& P, std::ostream& O) { return; // Header - O << "class " << P.Name << " : public Tool {\n" - << "public:\n"; + O << "class " << P.Name << " : public "; + if (P.isJoin()) + O << "JoinTool"; + else + O << "Tool"; + O << "{\npublic:\n"; EmitNameMethod(P, O); EmitInOutLanguageMethods(P, O);