From d752c3ffd84d2b16d736e01504a9d470863fb679 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Tue, 6 May 2008 16:36:50 +0000 Subject: [PATCH] More work on edge properties. Use Edge classes instead of strings in CompilationGraph. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50726 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvmc2/Common.td | 4 -- tools/llvmc2/CompilationGraph.cpp | 34 +++++++--------- tools/llvmc2/CompilationGraph.h | 25 +++++++----- tools/llvmc2/Example.td | 7 ++++ tools/llvmc2/Makefile | 7 +--- utils/TableGen/LLVMCCConfigurationEmitter.cpp | 40 +++++++++++++++---- 6 files changed, 69 insertions(+), 48 deletions(-) diff --git a/tools/llvmc2/Common.td b/tools/llvmc2/Common.td index 44358573764..30905a47d21 100644 --- a/tools/llvmc2/Common.td +++ b/tools/llvmc2/Common.td @@ -50,10 +50,6 @@ def required; def switch_on; def parameter_equals; def element_in_list; - -// Property combinators -// TOFIX: implement -def and; def or; // Map from suffixes to language names diff --git a/tools/llvmc2/CompilationGraph.cpp b/tools/llvmc2/CompilationGraph.cpp index 07b09e7390b..77c5896161f 100644 --- a/tools/llvmc2/CompilationGraph.cpp +++ b/tools/llvmc2/CompilationGraph.cpp @@ -32,14 +32,14 @@ CompilationGraph::CompilationGraph() { Node& CompilationGraph::getNode(const std::string& ToolName) { nodes_map_type::iterator I = NodesMap.find(ToolName); if (I == NodesMap.end()) - throw std::runtime_error("Node " + ToolName + " is not in graph"); + throw std::runtime_error("Node " + ToolName + " is not in the graph"); return I->second; } const Node& CompilationGraph::getNode(const std::string& ToolName) const { nodes_map_type::const_iterator I = NodesMap.find(ToolName); if (I == NodesMap.end()) - throw std::runtime_error("Node " + ToolName + " is not in graph!"); + throw std::runtime_error("Node " + ToolName + " is not in the graph!"); return I->second; } @@ -69,31 +69,23 @@ void CompilationGraph::insertNode(Tool* V) { } } -void CompilationGraph::insertEdge(const std::string& A, - const std::string& B) { - // TOTHINK: check this at compile-time? - if (B == "root") - throw std::runtime_error("Edges back to the root are not allowed!" - "Compilation graph should be acyclic!"); - +void CompilationGraph::insertEdge(const std::string& A, Edge* E) { if (A == "root") { - const Node& N = getNode(B); + const Node& N = getNode(E->ToolName()); const std::string& InputLanguage = N.ToolPtr->InputLanguage(); - ToolsMap[InputLanguage].push_back(B); + ToolsMap[InputLanguage].push_back(E->ToolName()); // Needed to support iteration via GraphTraits. - NodesMap["root"].AddEdge(new DefaultEdge(B)); + NodesMap["root"].AddEdge(E); } else { Node& N = getNode(A); - // Check that there is a node at B. - getNode(B); - N.AddEdge(new DefaultEdge(B)); + N.AddEdge(E); } } -// TOFIX: extend, add an ability to choose between different -// toolchains, support more interesting graph topologies. +// TOFIX: support edge properties. +// TOFIX: support more interesting graph topologies. int CompilationGraph::Build (const sys::Path& tempDir) const { PathVector JoinList; const Tool* JoinTool = 0; @@ -124,7 +116,11 @@ int CompilationGraph::Build (const sys::Path& tempDir) const { // Is this the last tool? if (!N->HasChildren() || CurTool->IsLast()) { - Out.appendComponent(In.getBasename()); + // Check if the first tool is also the last + if(Out.empty()) + Out.set(In.getBasename()); + else + Out.appendComponent(In.getBasename()); Out.appendSuffix(CurTool->OutputSuffix()); Last = true; } @@ -191,5 +187,5 @@ void CompilationGraph::writeGraph() { } void CompilationGraph::viewGraph() { - llvm::ViewGraph(this, "CompilationGraph"); + llvm::ViewGraph(this, "compilation-graph"); } diff --git a/tools/llvmc2/CompilationGraph.h b/tools/llvmc2/CompilationGraph.h index 85210dc499c..d953aeea900 100644 --- a/tools/llvmc2/CompilationGraph.h +++ b/tools/llvmc2/CompilationGraph.h @@ -28,6 +28,7 @@ namespace llvmcc { + // An edge in the graph. class Edge : public llvm::RefCountedBaseVPTR { public: Edge(const std::string& T) : ToolName_(T) {} @@ -40,13 +41,15 @@ namespace llvmcc { std::string ToolName_; }; - class DefaultEdge : public Edge { + // Edges with no properties are instances of this class. + class SimpleEdge : public Edge { public: - DefaultEdge(const std::string& T) : Edge(T) {} + SimpleEdge(const std::string& T) : Edge(T) {} bool isEnabled() const { return true;} bool isDefault() const { return true;} }; + // A node in the graph. struct Node { typedef llvm::SmallVector, 3> container_type; typedef container_type::iterator iterator; @@ -56,14 +59,14 @@ namespace llvmcc { Node(CompilationGraph* G) : OwningGraph(G) {} Node(CompilationGraph* G, Tool* T) : OwningGraph(G), ToolPtr(T) {} - bool HasChildren() const { return OutEdges.empty(); } + bool HasChildren() const { return !OutEdges.empty(); } iterator EdgesBegin() { return OutEdges.begin(); } const_iterator EdgesBegin() const { return OutEdges.begin(); } iterator EdgesEnd() { return OutEdges.end(); } const_iterator EdgesEnd() const { return OutEdges.end(); } - // E is a new-allocated pointer. + // Takes ownership of the object. void AddEdge(Edge* E) { OutEdges.push_back(llvm::IntrusiveRefCntPtr(E)); } @@ -93,16 +96,16 @@ namespace llvmcc { CompilationGraph(); - // insertVertex - insert a new node into the graph. + // insertVertex - insert a new node into the graph. Takes + // ownership of the object. void insertNode(Tool* T); - // insertEdge - Insert a new edge into the graph. This function - // assumes that both A and B have been already inserted. - void insertEdge(const std::string& A, const std::string& B); + // insertEdge - Insert a new edge into the graph. Takes ownership + // of the object. + void insertEdge(const std::string& A, Edge* E); - // Build - Build the target(s) from the set of the input - // files. Command-line options are passed implicitly as global - // variables. + // 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; // Return a reference to the node correponding to the given tool diff --git a/tools/llvmc2/Example.td b/tools/llvmc2/Example.td index d56f7f96358..79376efae68 100644 --- a/tools/llvmc2/Example.td +++ b/tools/llvmc2/Example.td @@ -21,9 +21,16 @@ def CompilationGraph : CompilationGraph<[ Edge, Edge, Edge, + Edge, Edge, Edge, + + OptionalEdge, + OptionalEdge, + OptionalEdge, + OptionalEdge, + Edge, Edge ]>; diff --git a/tools/llvmc2/Makefile b/tools/llvmc2/Makefile index 8fe1e818712..4cb967c3b6e 100644 --- a/tools/llvmc2/Makefile +++ b/tools/llvmc2/Makefile @@ -14,12 +14,7 @@ REQUIRES_EH := 1 include $(LEVEL)/Makefile.common -TOOLS_TARGET=default -ifeq ($(TOOLS_TARGET), default) - TOOLS_SOURCE=Example.td -else - TOOLS_SOURCE=ExampleWithOpt.td -endif +TOOLS_SOURCE=Example.td # TOFIX: integrate this part into Makefile.rules? # The degree of horrorshowness in that file is too much for me atm. diff --git a/utils/TableGen/LLVMCCConfigurationEmitter.cpp b/utils/TableGen/LLVMCCConfigurationEmitter.cpp index 92e2df18850..606510ed025 100644 --- a/utils/TableGen/LLVMCCConfigurationEmitter.cpp +++ b/utils/TableGen/LLVMCCConfigurationEmitter.cpp @@ -866,6 +866,8 @@ void FillInToolToLang (const ToolPropertiesList& TPList, } // Check that all output and input language names match. +// TOFIX: check for cycles. +// TOFIX: check for multiple default edges. void TypecheckGraph (Record* CompilationGraph, const ToolPropertiesList& TPList) { StringMap ToolToInLang; @@ -889,22 +891,36 @@ void TypecheckGraph (Record* CompilationGraph, if(A->getName() != "root" && IA->second != IB->second) throw "Edge " + A->getName() + "->" + B->getName() + ": output->input language mismatch"; + if(B->getName() == "root") + throw std::string("Edges back to the root are not allowed!"); } } -// Emit Edge* classes used for. +// Emit Edge* classes that represent edges in the graph. +// TOFIX: add edge properties. void EmitEdgeClasses (Record* CompilationGraph, const GlobalOptionDescriptions& OptDescs, std::ostream& O) { ListInit* edges = CompilationGraph->getValueAsListInit("edges"); for (unsigned i = 0; i < edges->size(); ++i) { - //Record* Edge = edges->getElementAsRecord(i); - //Record* A = Edge->getValueAsDef("a"); - //Record* B = Edge->getValueAsDef("b"); - //ListInit* Props = Edge->getValueAsListInit("props"); + Record* Edge = edges->getElementAsRecord(i); + Record* B = Edge->getValueAsDef("b"); + ListInit* Props = Edge->getValueAsListInit("props"); + + if (Props->empty()) + continue; + + O << "class Edge" << i << ": public Edge {\n" + << "public:\n" + << Indent1 << "Edge" << i << "() : Edge(\"" << B->getName() + << "\") {}\n"; + + O << Indent1 << "bool isEnabled() const { return true; }\n"; - O << "class Edge" << i << " {};\n\n"; + O << Indent1 << "bool isDefault() const { return false; }\n"; + + O << "};\n\n"; } } @@ -937,8 +953,16 @@ void EmitPopulateCompilationGraph (Record* CompilationGraph, Record* Edge = edges->getElementAsRecord(i); Record* A = Edge->getValueAsDef("a"); Record* B = Edge->getValueAsDef("b"); - O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", \"" - << B->getName() << "\");\n"; + ListInit* Props = Edge->getValueAsListInit("props"); + + O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", "; + + if (Props->empty()) + O << "new SimpleEdge(\"" << B->getName() << "\")"; + else + O << "new Edge" << i << "()"; + + O << ");\n"; } O << "}\n\n"; -- 2.34.1