[llvm-commits] [llvm] r59447 - in /llvm/trunk: include/llvm/CompilerDriver/Common.td tools/llvmc2/doc/LLVMC-Reference.rst tools/llvmc2/doc/LLVMC-Tutorial.rst tools/llvmc2/plugins/Base/Base.td tools/llvmc2/plugins/Clang/Clang.td tools/llvmc2/plugins/Simple/Simple.td utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Mon Nov 17 09:29:18 PST 2008


Author: foldr
Date: Mon Nov 17 11:29:18 2008
New Revision: 59447

URL: http://llvm.org/viewvc/llvm-project?rev=59447&view=rev
Log:
Add a layer of indirection to make plugins more flexible.

Use strings instead of TableGen defs in the compilation graph
definition. Makes it easier for the plugins to modify an existing graph.

Modified:
    llvm/trunk/include/llvm/CompilerDriver/Common.td
    llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst
    llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst
    llvm/trunk/tools/llvmc2/plugins/Base/Base.td
    llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td
    llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/include/llvm/CompilerDriver/Common.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CompilerDriver/Common.td?rev=59447&r1=59446&r2=59447&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CompilerDriver/Common.td (original)
+++ llvm/trunk/include/llvm/CompilerDriver/Common.td Mon Nov 17 11:29:18 2008
@@ -15,10 +15,6 @@
       list<dag> properties = l;
 }
 
-// Special Tool instance - the root node of the compilation graph.
-
-def root : Tool<[]>;
-
 // Possible Tool properties
 
 def in_language;
@@ -87,19 +83,19 @@
 
 // Compilation graph
 
-class EdgeBase<Tool t1, Tool t2, dag d> {
-      Tool a = t1;
-      Tool b = t2;
+class EdgeBase<string t1, string t2, dag d> {
+      string a = t1;
+      string b = t2;
       dag weight = d;
 }
 
-class Edge<Tool t1, Tool t2> : EdgeBase<t1, t2, (empty)>;
+class Edge<string t1, string t2> : EdgeBase<t1, t2, (empty)>;
 
 // Edge and SimpleEdge are synonyms.
-class SimpleEdge<Tool t1, Tool t2> : EdgeBase<t1, t2, (empty)>;
+class SimpleEdge<string t1, string t2> : EdgeBase<t1, t2, (empty)>;
 
 // Optionally enabled edge.
-class OptionalEdge<Tool t1, Tool t2, dag props> : EdgeBase<t1, t2, props>;
+class OptionalEdge<string t1, string t2, dag props> : EdgeBase<t1, t2, props>;
 
 class CompilationGraph<list<EdgeBase> lst> {
       list<EdgeBase> edges = lst;

Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst?rev=59447&r1=59446&r2=59447&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst (original)
+++ llvm/trunk/tools/llvmc2/doc/LLVMC-Reference.rst Mon Nov 17 11:29:18 2008
@@ -158,7 +158,7 @@
    include "llvm/CompilerDriver/Common.td"
    // And optionally:
    // include "llvm/CompilerDriver/Tools.td"
-   // which contains tool definitions.
+   // which contains some useful tool definitions.
 
 Internally, LLVMC stores information about possible source
 transformations in form of a graph. Nodes in this graph represent
@@ -171,19 +171,19 @@
 ``plugins/Base/Base.td`` for an example) is just a list of edges::
 
     def CompilationGraph : CompilationGraph<[
-        Edge<root, llvm_gcc_c>,
-        Edge<root, llvm_gcc_assembler>,
+        Edge<"root", "llvm_gcc_c">,
+        Edge<"root", "llvm_gcc_assembler">,
         ...
 
-        Edge<llvm_gcc_c, llc>,
-        Edge<llvm_gcc_cpp, llc>,
+        Edge<"llvm_gcc_c", "llc">,
+        Edge<"llvm_gcc_cpp", "llc">,
         ...
 
-        OptionalEdge<llvm_gcc_c, opt, [(switch_on "opt")]>,
-        OptionalEdge<llvm_gcc_cpp, opt, [(switch_on "opt")]>,
+        OptionalEdge<"llvm_gcc_c", "opt", [(switch_on "opt")]>,
+        OptionalEdge<"llvm_gcc_cpp", "opt", [(switch_on "opt")]>,
         ...
 
-        OptionalEdge<llvm_gcc_assembler, llvm_gcc_cpp_linker,
+        OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker",
             (case (input_languages_contain "c++"), (inc_weight),
                   (or (parameter_equals "linker", "g++"),
                       (parameter_equals "linker", "c++")), (inc_weight))>,
@@ -193,7 +193,10 @@
 
 As you can see, the edges can be either default or optional, where
 optional edges are differentiated by an additional ``case`` expression
-used to calculate the weight of this edge.
+used to calculate the weight of this edge. Notice also that we refer
+to tools via their names (as strings). This allows us to add edges to
+an existing compilation graph without having to include all tool
+definitions that it uses.
 
 The default edges are assigned a weight of 1, and optional edges get a
 weight of 0 + 2*N where N is the number of tests that evaluated to

Modified: llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst?rev=59447&r1=59446&r2=59447&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst (original)
+++ llvm/trunk/tools/llvmc2/doc/LLVMC-Tutorial.rst Mon Nov 17 11:29:18 2008
@@ -66,7 +66,7 @@
     def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>;
 
     // Compilation graph
-    def CompilationGraph : CompilationGraph<[Edge<root, gcc>]>;
+    def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>;
 
 As you can see, this file consists of three parts: tool descriptions,
 language map, and the compilation graph definition.

Modified: llvm/trunk/tools/llvmc2/plugins/Base/Base.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Base/Base.td?rev=59447&r1=59446&r2=59447&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/plugins/Base/Base.td (original)
+++ llvm/trunk/tools/llvmc2/plugins/Base/Base.td Mon Nov 17 11:29:18 2008
@@ -17,42 +17,42 @@
 // Toolchains
 
 def CompilationGraph : CompilationGraph<[
-    Edge<root, llvm_gcc_c>,
-    Edge<root, llvm_gcc_assembler>,
-    Edge<root, llvm_gcc_cpp>,
-    Edge<root, llvm_gcc_m>,
-    Edge<root, llvm_gcc_mxx>,
-    Edge<root, llvm_as>,
-
-    Edge<llvm_gcc_c, llc>,
-    Edge<llvm_gcc_cpp, llc>,
-    Edge<llvm_gcc_m, llc>,
-    Edge<llvm_gcc_mxx, llc>,
-    Edge<llvm_as, llc>,
-
-    OptionalEdge<llvm_gcc_c, opt, (case (switch_on "opt"), (inc_weight))>,
-    OptionalEdge<llvm_gcc_cpp, opt, (case (switch_on "opt"), (inc_weight))>,
-    OptionalEdge<llvm_gcc_m, opt, (case (switch_on "opt"), (inc_weight))>,
-    OptionalEdge<llvm_gcc_mxx, 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,
+    Edge<"root", "llvm_gcc_c">,
+    Edge<"root", "llvm_gcc_assembler">,
+    Edge<"root", "llvm_gcc_cpp">,
+    Edge<"root", "llvm_gcc_m">,
+    Edge<"root", "llvm_gcc_mxx">,
+    Edge<"root", "llvm_as">,
+
+    Edge<"llvm_gcc_c", "llc">,
+    Edge<"llvm_gcc_cpp", "llc">,
+    Edge<"llvm_gcc_m", "llc">,
+    Edge<"llvm_gcc_mxx", "llc">,
+    Edge<"llvm_as", "llc">,
+
+    OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), (inc_weight))>,
+    OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), (inc_weight))>,
+    OptionalEdge<"llvm_gcc_m", "opt", (case (switch_on "opt"), (inc_weight))>,
+    OptionalEdge<"llvm_gcc_mxx", "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",
                  (case
                      (or (input_languages_contain "c++"),
-                         (input_languages_contain "objective-c++")), 
+                         (input_languages_contain "objective-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,
+    Edge<"root", "llvm_gcc_linker">,
+    OptionalEdge<"root", "llvm_gcc_cpp_linker",
                  (case
                      (or (input_languages_contain "c++"),
-                         (input_languages_contain "objective-c++")), 
+                         (input_languages_contain "objective-c++")),
                      (inc_weight),
                      (or (parameter_equals "linker", "g++"),
                          (parameter_equals "linker", "c++")), (inc_weight))>

Modified: llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td?rev=59447&r1=59446&r2=59447&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td (original)
+++ llvm/trunk/tools/llvmc2/plugins/Clang/Clang.td Mon Nov 17 11:29:18 2008
@@ -76,11 +76,11 @@
 // Compilation graph
 
 def CompilationGraph : CompilationGraph<[
-    Edge<root, clang_c>,
-    Edge<root, clang_cpp>,
-    Edge<root, clang_objective_c>,
-    Edge<clang_c, llvm_ld>,
-    Edge<clang_cpp, llvm_ld>,
-    Edge<clang_objective_c, llvm_ld>
+    Edge<"root", "clang_c">,
+    Edge<"root", "clang_cpp">,
+    Edge<"root", "clang_objective_c">,
+    Edge<"clang_c", "llvm_ld">,
+    Edge<"clang_cpp", "llvm_ld">,
+    Edge<"clang_objective_c", "llvm_ld">
     ]>;
 

Modified: llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td?rev=59447&r1=59446&r2=59447&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td (original)
+++ llvm/trunk/tools/llvmc2/plugins/Simple/Simple.td Mon Nov 17 11:29:18 2008
@@ -27,4 +27,4 @@
 
 def LanguageMap : LanguageMap<[LangToSuffixes<"c", ["c"]>]>;
 
-def CompilationGraph : CompilationGraph<[Edge<root, gcc>]>;
+def CompilationGraph : CompilationGraph<[Edge<"root", "gcc">]>;

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

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Mon Nov 17 11:29:18 2008
@@ -764,11 +764,11 @@
 }
 
 
-/// CollectPropertiesFromOptionList - Gather information about
-/// *global* option properties from the OptionList.
-void CollectPropertiesFromOptionList (RecordVector::const_iterator B,
-                                      RecordVector::const_iterator E,
-                                      GlobalOptionDescriptions& OptDescs)
+/// CollectPropertiesFromOptionLists - Gather information about
+/// *global* option properties from all OptionLists.
+void CollectPropertiesFromOptionLists (RecordVector::const_iterator B,
+                                       RecordVector::const_iterator E,
+                                       GlobalOptionDescriptions& OptDescs)
 {
   // Iterate over a properties list of every Tool definition
   for (;B!=E;++B) {
@@ -805,7 +805,7 @@
     const GlobalOptionDescription& Val = B->second;
     if (!nonSuperfluousOptions.count(Val.Name)
         && Val.Type != OptionType::Alias)
-      cerr << "Warning: option '-" << Val.Name << "' has no effect! "
+      llvm::cerr << "Warning: option '-" << Val.Name << "' has no effect! "
         "Probable cause: this option is specified only in the OptionList.\n";
   }
 }
@@ -1448,29 +1448,31 @@
 /// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function.
 void EmitPopulateLanguageMap (const RecordKeeper& Records, std::ostream& O)
 {
-  // Get the relevant field out of RecordKeeper
-  Record* LangMapRecord = Records.getDef("LanguageMap");
-  if (!LangMapRecord)
-    throw std::string("Language map definition not found!");
-
-  ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
-  if (!LangsToSuffixesList)
-    throw std::string("Error in the language map definition!");
-
   // Generate code
   O << "namespace {\n\n";
   O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
 
-  for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
-    Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
+  // Get the relevant field out of RecordKeeper
+  Record* LangMapRecord = Records.getDef("LanguageMap");
 
-    const std::string& Lang = LangToSuffixes->getValueAsString("lang");
-    const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
+  // It is allowed for a plugin to have no language map.
+  if (LangMapRecord) {
 
-    for (unsigned i = 0; i < Suffixes->size(); ++i)
-      O << Indent1 << "langMap[\""
-        << InitPtrToString(Suffixes->getElement(i))
-        << "\"] = \"" << Lang << "\";\n";
+    ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
+    if (!LangsToSuffixesList)
+      throw std::string("Error in the language map definition!");
+
+    for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
+      Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
+
+      const std::string& Lang = LangToSuffixes->getValueAsString("lang");
+      const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
+
+      for (unsigned i = 0; i < Suffixes->size(); ++i)
+        O << Indent1 << "langMap[\""
+          << InitPtrToString(Suffixes->getElement(i))
+          << "\"] = \"" << Lang << "\";\n";
+    }
   }
 
   O << "}\n\n}\n\n";
@@ -1492,13 +1494,11 @@
 }
 
 /// TypecheckGraph - Check that names for output and input languages
-/// on all edges do match.
-// TOFIX: It would be nice if this function also checked for cycles
-// and multiple default edges in the graph (better error
-// reporting). Unfortunately, it is awkward to do right now because
-// our intermediate representation is not sufficiently
-// sophisticated. Algorithms like these require a real graph instead of
-// an AST.
+/// on all edges do match. This doesn't do much when the information
+/// about the whole graph is not available (i.e. when compiling most
+/// plugins).
+// TODO: add a --check-graph switch to llvmc2. It would also make it
+// possible to detect cycles and multiple default edges.
 void TypecheckGraph (Record* CompilationGraph,
                      const ToolPropertiesList& TPList) {
   StringMap<StringSet<> > ToolToInLang;
@@ -1511,18 +1511,18 @@
 
   for (unsigned i = 0; i < edges->size(); ++i) {
     Record* Edge = edges->getElementAsRecord(i);
-    Record* A = Edge->getValueAsDef("a");
-    Record* B = Edge->getValueAsDef("b");
-    StringMap<std::string>::iterator IA = ToolToOutLang.find(A->getName());
-    StringMap<StringSet<> >::iterator IB = ToolToInLang.find(B->getName());
-    if (IA == IAE)
-      throw A->getName() + ": no such tool!";
-    if (IB == IBE)
-      throw B->getName() + ": no such tool!";
-    if (A->getName() != "root" && IB->second.count(IA->second) == 0)
-      throw "Edge " + A->getName() + "->" + B->getName()
-        + ": output->input language mismatch";
-    if (B->getName() == "root")
+    const std::string& A = Edge->getValueAsString("a");
+    const std::string& B = Edge->getValueAsString("b");
+    StringMap<std::string>::iterator IA = ToolToOutLang.find(A);
+    StringMap<StringSet<> >::iterator IB = ToolToInLang.find(B);
+
+    if (A != "root") {
+      if (IA != IAE && IB != IBE && IB->second.count(IA->second) == 0)
+        throw "Edge " + A + "->" + B
+          + ": output->input language mismatch";
+    }
+
+    if (B == "root")
       throw std::string("Edges back to the root are not allowed!");
   }
 }
@@ -1578,13 +1578,13 @@
 
   for (unsigned i = 0; i < edges->size(); ++i) {
     Record* Edge = edges->getElementAsRecord(i);
-    Record* B = Edge->getValueAsDef("b");
+    const std::string& B = Edge->getValueAsString("b");
     DagInit* Weight = Edge->getValueAsDag("weight");
 
     if (isDagEmpty(Weight))
       continue;
 
-    EmitEdgeClass(i, B->getName(), Weight, OptDescs, O);
+    EmitEdgeClass(i, B, Weight, OptDescs, O);
   }
 }
 
@@ -1605,13 +1605,12 @@
 
   for (unsigned i = 0; i < edges->size(); ++i) {
     Record* Edge = edges->getElementAsRecord(i);
-    Record* A = Edge->getValueAsDef("a");
-    Record* B = Edge->getValueAsDef("b");
+    const std::string& A = Edge->getValueAsString("a");
+    const std::string& B = Edge->getValueAsString("b");
 
-    if (A->getName() != "root")
-      ToolsInGraph.insert(A->getName());
-    if (B->getName() != "root")
-      ToolsInGraph.insert(B->getName());
+    if (A != "root")
+      ToolsInGraph.insert(A);
+    ToolsInGraph.insert(B);
   }
 
   for (llvm::StringSet<>::iterator B = ToolsInGraph.begin(),
@@ -1624,14 +1623,14 @@
 
   for (unsigned i = 0; i < edges->size(); ++i) {
     Record* Edge = edges->getElementAsRecord(i);
-    Record* A = Edge->getValueAsDef("a");
-    Record* B = Edge->getValueAsDef("b");
+    const std::string& A = Edge->getValueAsString("a");
+    const std::string& B = Edge->getValueAsString("b");
     DagInit* Weight = Edge->getValueAsDag("weight");
 
-    O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", ";
+    O << Indent1 << "G.insertEdge(\"" << A << "\", ";
 
     if (isDagEmpty(Weight))
-      O << "new SimpleEdge(\"" << B->getName() << "\")";
+      O << "new SimpleEdge(\"" << B << "\")";
     else
       O << "new Edge" << i << "()";
 
@@ -1763,6 +1762,7 @@
   EmitIncludes(O);
 
   // Get a list of all defined Tools.
+
   RecordVector Tools = Records.getAllDerivedDefinitions("Tool");
   if (Tools.empty())
     throw std::string("No tool definitions found!");
@@ -1773,8 +1773,8 @@
   CollectToolProperties(Tools.begin(), Tools.end(), tool_props, opt_descs);
 
   RecordVector OptionLists = Records.getAllDerivedDefinitions("OptionList");
-  CollectPropertiesFromOptionList(OptionLists.begin(), OptionLists.end(),
-                                  opt_descs);
+  CollectPropertiesFromOptionLists(OptionLists.begin(), OptionLists.end(),
+                                   opt_descs);
 
   // Check that there are no options without side effects (specified
   // only in the OptionList).
@@ -1795,6 +1795,9 @@
          E = tool_props.end(); B!=E; ++B)
     EmitToolClassDefinition(*(*B), opt_descs, O);
 
+  // TOTHINK: Nothing actually prevents us from having multiple
+  // compilation graphs in a single plugin; OTOH, I do not see how
+  // that could be useful.
   Record* CompilationGraphRecord = Records.getDef("CompilationGraph");
   if (!CompilationGraphRecord)
     throw std::string("Compilation graph description not found!");





More information about the llvm-commits mailing list