[llvm-commits] [llvm] r51727 - in /llvm/trunk: tools/llvmc2/Common.td tools/llvmc2/Graph.td tools/llvmc2/Makefile utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Thu May 29 23:08:50 PDT 2008


Author: foldr
Date: Fri May 30 01:08:50 2008
New Revision: 51727

URL: http://llvm.org/viewvc/llvm-project?rev=51727&view=rev
Log:
Add a generalised 'case' construct.

Besides assigning edge weights, it will also be used by the cmd_line tool property.

Modified:
    llvm/trunk/tools/llvmc2/Common.td
    llvm/trunk/tools/llvmc2/Graph.td
    llvm/trunk/tools/llvmc2/Makefile
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/tools/llvmc2/Common.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Common.td?rev=51727&r1=51726&r2=51727&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Common.td (original)
+++ llvm/trunk/tools/llvmc2/Common.td Fri May 30 01:08:50 2008
@@ -45,19 +45,26 @@
 def help;
 def required;
 
-// Possible edge properties
+// Marker for an empty DAG.
+def empty;
 
-// 'Atomic' properties.
+// The 'case' construct.
+def case;
+
+// Primitive tests.
 def switch_on;
 def parameter_equals;
 def element_in_list;
-def if_input_languages_contain;
+def input_languages_contain;
 
-// Edge property combinators.
-def weight;
+// Boolean operators.
 def and;
 def or;
 
+// Increase/decrease the edge weight.
+def inc_weight;
+def dec_weight;
+
 // Map from suffixes to language names
 
 class LangToSuffixes<string str, list<string> lst> {
@@ -71,19 +78,19 @@
 
 // Compilation graph
 
-class EdgeBase<Tool t1, Tool t2, list<dag> lst> {
+class EdgeBase<Tool t1, Tool t2, dag d> {
       Tool a = t1;
       Tool b = t2;
-      list<dag> props = lst;
+      dag weight = d;
 }
 
-class Edge<Tool t1, Tool t2> : EdgeBase<t1, t2, []>;
+class Edge<Tool t1, Tool t2> : EdgeBase<t1, t2, (empty)>;
 
 // Edge and SimpleEdge are synonyms.
-class SimpleEdge<Tool t1, Tool t2> : EdgeBase<t1, t2, []>;
+class SimpleEdge<Tool t1, Tool t2> : EdgeBase<t1, t2, (empty)>;
 
 // Optionally enabled edge.
-class OptionalEdge<Tool t1, Tool t2, list<dag> lst> : EdgeBase<t1, t2, lst>;
+class OptionalEdge<Tool t1, Tool t2, dag props> : EdgeBase<t1, t2, props>;
 
 class CompilationGraph<list<EdgeBase> lst> {
       list<EdgeBase> edges = lst;

Modified: llvm/trunk/tools/llvmc2/Graph.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Graph.td?rev=51727&r1=51726&r2=51727&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Graph.td (original)
+++ llvm/trunk/tools/llvmc2/Graph.td Fri May 30 01:08:50 2008
@@ -26,22 +26,24 @@
     Edge<llvm_gcc_cpp, llc>,
     Edge<llvm_as, llc>,
 
-    OptionalEdge<llvm_gcc_c, opt, [(switch_on "opt")]>,
-    OptionalEdge<llvm_gcc_cpp, opt, [(switch_on "opt")]>,
-    OptionalEdge<llvm_as, opt, [(switch_on "opt")]>,
+    OptionalEdge<llvm_gcc_c, opt, (case (switch_on "opt"), (inc_weight))>,
+    OptionalEdge<llvm_gcc_cpp, opt, (case (switch_on "opt"), (inc_weight))>,
+    OptionalEdge<llvm_as, opt, (case (switch_on "opt"), (inc_weight))>,
     Edge<opt, llc>,
 
     Edge<llc, llvm_gcc_assembler>,
     Edge<llvm_gcc_assembler, llvm_gcc_linker>,
     OptionalEdge<llvm_gcc_assembler, llvm_gcc_cpp_linker,
-                 [(if_input_languages_contain "c++"),
-                  (or (parameter_equals "linker", "g++"),
-                      (parameter_equals "linker", "c++"))]>,
+                 (case
+                     (input_languages_contain "c++"), (inc_weight),
+                     (or (parameter_equals "linker", "g++"),
+                         (parameter_equals "linker", "c++")), (inc_weight))>,
 
 
     Edge<root, llvm_gcc_linker>,
     OptionalEdge<root, llvm_gcc_cpp_linker,
-                 [(if_input_languages_contain "c++"),
-                  (or (parameter_equals "linker", "g++"),
-                      (parameter_equals "linker", "c++"))]>
+                 (case
+                     (input_languages_contain "c++"), (inc_weight),
+                     (or (parameter_equals "linker", "g++"),
+                         (parameter_equals "linker", "c++")), (inc_weight))>
     ]>;

Modified: llvm/trunk/tools/llvmc2/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Makefile?rev=51727&r1=51726&r2=51727&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Makefile (original)
+++ llvm/trunk/tools/llvmc2/Makefile Fri May 30 01:08:50 2008
@@ -14,15 +14,15 @@
 
 include $(LEVEL)/Makefile.common
 
-GRAPH = Graph.td
-TOOLS_SOURCE=$(GRAPH) Tools.td Common.td
+GRAPH=Graph.td
+TOOLS=Tools.td
+TOOLS_SOURCE=$(GRAPH) $(TOOLS) Common.td
 
 # TOFIX: integrate this part into Makefile.rules?
 # The degree of horrorshowness in that file is too much for me atm.
-$(ObjDir)/AutoGenerated.inc.tmp: $(TOOLS_SOURCE) $(ObjDir)/.dir
-	$(Echo) "Building LLVMCC configuration library with tblgen"
+$(ObjDir)/AutoGenerated.inc.tmp: $(TOOLS_SOURCE) $(ObjDir)/.dir $(TBLGEN)
+	$(Echo) "Building LLVMC configuration library with tblgen"
 	$(Verb) $(TableGen) -gen-llvmc -o $(call SYSPATH, $@) $<
 
 AutoGenerated.inc : $(ObjDir)/AutoGenerated.inc.tmp
 	$(Verb) $(CMP) -s $@ $< || $(CP) $< $@
-

Modified: llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp?rev=51727&r1=51726&r2=51727&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Fri May 30 01:08:50 2008
@@ -68,15 +68,18 @@
   return val;
 }
 
-
 // checkNumberOfArguments - Ensure that the number of args in d is
-// less than or equal to min_arguments, otherwise throw an exception .
+// less than or equal to min_arguments, otherwise throw an exception.
 void checkNumberOfArguments (const DagInit* d, unsigned min_arguments) {
   if (d->getNumArgs() < min_arguments)
     throw "Property " + d->getOperator()->getAsString()
       + " has too few arguments!";
 }
 
+// isDagEmpty - is this DAG marked with an empty marker?
+bool isDagEmpty (const DagInit* d) {
+  return d->getOperator()->getAsString() == "empty";
+}
 
 //===----------------------------------------------------------------------===//
 /// Back-end specific code
@@ -974,21 +977,21 @@
   }
 }
 
-/// EmitEdgePropertyTest1Arg - Helper function used by
-/// EmitEdgePropertyTest.
-bool EmitEdgePropertyTest1Arg(const std::string& PropName,
-                              const DagInit& Prop,
-                              const GlobalOptionDescriptions& OptDescs,
-                              std::ostream& O) {
-  checkNumberOfArguments(&Prop, 1);
-  const std::string& OptName = InitPtrToString(Prop.getArg(0));
-  if (PropName == "switch_on") {
+/// EmitCaseTest1Arg - Helper function used by
+/// EmitCaseConstructHandler.
+bool EmitCaseTest1Arg(const std::string& TestName,
+                      const DagInit& d,
+                      const GlobalOptionDescriptions& OptDescs,
+                      std::ostream& O) {
+  checkNumberOfArguments(&d, 1);
+  const std::string& OptName = InitPtrToString(d.getArg(0));
+  if (TestName == "switch_on") {
     const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
     if (OptDesc.Type != OptionType::Switch)
       throw OptName + ": incorrect option type!";
     O << OptDesc.GenVariableName();
     return true;
-  } else if (PropName == "if_input_languages_contain") {
+  } else if (TestName == "input_languages_contain") {
     O << "InLangs.count(\"" << OptName << "\") != 0";
     return true;
   }
@@ -996,31 +999,32 @@
   return false;
 }
 
-/// EmitEdgePropertyTest2Args - Helper function used by
-/// EmitEdgePropertyTest.
-bool EmitEdgePropertyTest2Args(const std::string& PropName,
-                               const DagInit& Prop,
-                               const GlobalOptionDescriptions& OptDescs,
-                               std::ostream& O) {
-  checkNumberOfArguments(&Prop, 2);
-  const std::string& OptName = InitPtrToString(Prop.getArg(0));
-  const std::string& OptArg = InitPtrToString(Prop.getArg(1));
+/// EmitCaseTest2Args - Helper function used by
+/// EmitCaseConstructHandler.
+bool EmitCaseTest2Args(const std::string& TestName,
+                       const DagInit& d,
+                       const char* IndentLevel,
+                       const GlobalOptionDescriptions& OptDescs,
+                       std::ostream& O) {
+  checkNumberOfArguments(&d, 2);
+  const std::string& OptName = InitPtrToString(d.getArg(0));
+  const std::string& OptArg = InitPtrToString(d.getArg(1));
   const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
 
-  if (PropName == "parameter_equals") {
+  if (TestName == "parameter_equals") {
     if (OptDesc.Type != OptionType::Parameter
         && OptDesc.Type != OptionType::Prefix)
       throw OptName + ": incorrect option type!";
     O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
     return true;
   }
-  else if (PropName == "element_in_list") {
+  else if (TestName == "element_in_list") {
     if (OptDesc.Type != OptionType::ParameterList
         && OptDesc.Type != OptionType::PrefixList)
       throw OptName + ": incorrect option type!";
     const std::string& VarName = OptDesc.GenVariableName();
     O << "std::find(" << VarName << ".begin(),\n"
-      << Indent3 << VarName << ".end(), \""
+      << IndentLevel << Indent1 << VarName << ".end(), \""
       << OptArg << "\") != " << VarName << ".end()";
     return true;
   }
@@ -1029,47 +1033,95 @@
 }
 
 // Forward declaration.
-void EmitEdgePropertyTest(const DagInit& Prop,
-                          const GlobalOptionDescriptions& OptDescs,
-                          std::ostream& O);
+// EmitLogicalOperationTest and EmitCaseTest are mutually recursive.
+void EmitCaseTest(const DagInit& d, const char* IndentLevel,
+                  const GlobalOptionDescriptions& OptDescs,
+                  std::ostream& O);
 
 /// EmitLogicalOperationTest - Helper function used by
-/// EmitEdgePropertyTest.
-void EmitLogicalOperationTest(const DagInit& Prop, const char* LogicOp,
+/// EmitCaseConstructHandler.
+void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp,
+                              const char* IndentLevel,
                               const GlobalOptionDescriptions& OptDescs,
                               std::ostream& O) {
   O << '(';
-  for (unsigned j = 0, NumArgs = Prop.getNumArgs(); j < NumArgs; ++j) {
-    const DagInit& InnerProp = InitPtrToDagInitRef(Prop.getArg(j));
-    EmitEdgePropertyTest(InnerProp, OptDescs, O);
+  for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
+    const DagInit& InnerTest = InitPtrToDagInitRef(d.getArg(j));
+    EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
     if (j != NumArgs - 1)
-      O << ")\n" << Indent3 << ' ' << LogicOp << " (";
+      O << ")\n" << IndentLevel << Indent1 << ' ' << LogicOp << " (";
     else
       O << ')';
   }
 }
 
-/// EmitEdgePropertyTest - Helper function used by EmitEdgeClass.
-void EmitEdgePropertyTest(const DagInit& Prop,
-                          const GlobalOptionDescriptions& OptDescs,
-                          std::ostream& O) {
-  const std::string& PropName = Prop.getOperator()->getAsString();
-
-  if (PropName == "and")
-    EmitLogicalOperationTest(Prop, "&&", OptDescs, O);
-  else if (PropName == "or")
-    EmitLogicalOperationTest(Prop, "||", OptDescs, O);
-  else if (EmitEdgePropertyTest1Arg(PropName, Prop, OptDescs, O))
+/// EmitCaseTest - Helper function used by EmitCaseConstructHandler.
+void EmitCaseTest(const DagInit& d, const char* IndentLevel,
+                  const GlobalOptionDescriptions& OptDescs,
+                  std::ostream& O) {
+  const std::string& TestName = d.getOperator()->getAsString();
+
+  if (TestName == "and")
+    EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O);
+  else if (TestName == "or")
+    EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O);
+  else if (EmitCaseTest1Arg(TestName, d, OptDescs, O))
     return;
-  else if (EmitEdgePropertyTest2Args(PropName, Prop, OptDescs, O))
+  else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O))
     return;
   else
-    throw PropName + ": unknown edge property!";
+    throw TestName + ": unknown edge property!";
+}
+
+// Emit code that handles the 'case' construct.
+// Takes a function object that should emit code for every case clause.
+template <typename F>
+void EmitCaseConstructHandler(DagInit* d, const char* IndentLevel,
+                              const F& Callback,
+                              const GlobalOptionDescriptions& OptDescs,
+                              std::ostream& O) {
+  assert(d->getOperator()->getAsString() == "case");
+
+  for (DagInit::arg_iterator B = d->arg_begin(), E = d->arg_end();
+       B != E; ++B) {
+    const DagInit& Test = InitPtrToDagInitRef(*B);
+    O << IndentLevel << "if (";
+    EmitCaseTest(Test, IndentLevel, OptDescs, O);
+    O << ") {\n";
+
+    ++B;
+    if (B == E)
+      throw "Case construct handler: no corresponding action "
+        "found for the test " + Test.getAsString() + '!';
+
+    const DagInit& Action = InitPtrToDagInitRef(*B);
+    Callback(IndentLevel, Action, O);
+    O << IndentLevel << "}\n";
+  }
+}
+
+// Helper function passed to EmitCaseConstructHandler by EmitEdgeClass.
+void IncDecWeight(const char* IndentLevel,
+                  const DagInit& d, std::ostream& O) {
+  const std::string& OpName = d.getOperator()->getAsString();
+
+  if (OpName == "inc_weight")
+    O << IndentLevel << Indent1 << "ret += ";
+  else if (OpName == "dec_weight")
+    O << IndentLevel << Indent1 << "ret -= ";
+  else
+    throw "Unknown operator in edge properties list: " + OpName + '!';
+
+  if (d.getNumArgs() > 0)
+    O << InitPtrToInt(d.getArg(0)) << ";\n";
+  else
+    O << "2;\n";
+
 }
 
 /// EmitEdgeClass - Emit a single Edge# class.
 void EmitEdgeClass(unsigned N, const std::string& Target,
-                   ListInit* Props, const GlobalOptionDescriptions& OptDescs,
+                   DagInit* Case, const GlobalOptionDescriptions& OptDescs,
                    std::ostream& O) {
 
   // Class constructor.
@@ -1082,26 +1134,8 @@
     << Indent1 << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n"
     << Indent2 << "unsigned ret = 0;\n";
 
-  // Emit tests for every edge property.
-  for (size_t i = 0, PropsSize = Props->size(); i < PropsSize; ++i) {
-    const DagInit& Prop = InitPtrToDagInitRef(Props->getElement(i));
-    const std::string& PropName = Prop.getOperator()->getAsString();
-    unsigned N = 2;
-
-    O << Indent2 << "if (";
-
-    if (PropName == "weight") {
-      checkNumberOfArguments(&Prop, 2);
-      N = InitPtrToInt(Prop.getArg(0));
-      const DagInit& InnerProp = InitPtrToDagInitRef(Prop.getArg(1));
-      EmitEdgePropertyTest(InnerProp, OptDescs, O);
-    }
-    else {
-      EmitEdgePropertyTest(Prop, OptDescs, O);
-    }
-
-    O << ")\n" << Indent3 << "ret += " << N << ";\n";
-  }
+  // Handle the 'case' construct.
+  EmitCaseConstructHandler(Case, Indent2, IncDecWeight, OptDescs, O);
 
   O << Indent2 << "return ret;\n"
     << Indent1 << "};\n\n};\n\n";
@@ -1116,12 +1150,12 @@
   for (unsigned i = 0; i < edges->size(); ++i) {
     Record* Edge = edges->getElementAsRecord(i);
     Record* B = Edge->getValueAsDef("b");
-    ListInit* Props = Edge->getValueAsListInit("props");
+    DagInit* Weight = Edge->getValueAsDag("weight");
 
-    if (Props->empty())
+    if (isDagEmpty(Weight))
       continue;
 
-    EmitEdgeClass(i, B->getName(), Props, OptDescs, O);
+    EmitEdgeClass(i, B->getName(), Weight, OptDescs, O);
   }
 }
 
@@ -1156,11 +1190,11 @@
     Record* Edge = edges->getElementAsRecord(i);
     Record* A = Edge->getValueAsDef("a");
     Record* B = Edge->getValueAsDef("b");
-    ListInit* Props = Edge->getValueAsListInit("props");
+    DagInit* Weight = Edge->getValueAsDag("weight");
 
     O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", ";
 
-    if (Props->empty())
+    if (isDagEmpty(Weight))
       O << "new SimpleEdge(\"" << B->getName() << "\")";
     else
       O << "new Edge" << i << "()";





More information about the llvm-commits mailing list