diff --git a/llvm/tools/llvmc2/Common.td b/llvm/tools/llvmc2/Common.td index 44358573764a..30905a47d21f 100644 --- a/llvm/tools/llvmc2/Common.td +++ b/llvm/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/llvm/tools/llvmc2/CompilationGraph.cpp b/llvm/tools/llvmc2/CompilationGraph.cpp index 07b09e7390b7..77c5896161fc 100644 --- a/llvm/tools/llvmc2/CompilationGraph.cpp +++ b/llvm/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/llvm/tools/llvmc2/CompilationGraph.h b/llvm/tools/llvmc2/CompilationGraph.h index 85210dc499c3..d953aeea9003 100644 --- a/llvm/tools/llvmc2/CompilationGraph.h +++ b/llvm/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/llvm/tools/llvmc2/Example.td b/llvm/tools/llvmc2/Example.td index d56f7f96358b..79376efae687 100644 --- a/llvm/tools/llvmc2/Example.td +++ b/llvm/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/llvm/tools/llvmc2/Makefile b/llvm/tools/llvmc2/Makefile index 8fe1e8187127..4cb967c3b6ed 100644 --- a/llvm/tools/llvmc2/Makefile +++ b/llvm/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/llvm/utils/TableGen/LLVMCCConfigurationEmitter.cpp b/llvm/utils/TableGen/LLVMCCConfigurationEmitter.cpp index 92e2df188508..606510ed0251 100644 --- a/llvm/utils/TableGen/LLVMCCConfigurationEmitter.cpp +++ b/llvm/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"); - O << "class Edge" << i << " {};\n\n"; + 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 << 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";