[llvm-commits] [llvm] r51742 - in /llvm/trunk: tools/llvmc2/CompilationGraph.cpp tools/llvmc2/Tool.h tools/llvmc2/examples/Clang.td utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Thu May 29 23:18:16 PDT 2008


Author: foldr
Date: Fri May 30 01:18:16 2008
New Revision: 51742

URL: http://llvm.org/viewvc/llvm-project?rev=51742&view=rev
Log:
Make it possible to have multiple input languages for a single tool.

Modified:
    llvm/trunk/tools/llvmc2/CompilationGraph.cpp
    llvm/trunk/tools/llvmc2/Tool.h
    llvm/trunk/tools/llvmc2/examples/Clang.td
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/tools/llvmc2/CompilationGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/CompilationGraph.cpp?rev=51742&r1=51741&r2=51742&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/CompilationGraph.cpp (original)
+++ llvm/trunk/tools/llvmc2/CompilationGraph.cpp Fri May 30 01:18:16 2008
@@ -115,16 +115,18 @@
   }
 }
 
-void CompilationGraph::insertEdge(const std::string& A, Edge* E) {
-  Node& B = getNode(E->ToolName());
+void CompilationGraph::insertEdge(const std::string& A, Edge* Edg) {
+  Node& B = getNode(Edg->ToolName());
   if (A == "root") {
-    const std::string& InputLanguage = B.ToolPtr->InputLanguage();
-    ToolsMap[InputLanguage].push_back(IntrusiveRefCntPtr<Edge>(E));
-    NodesMap["root"].AddEdge(E);
+    const StrVector& InputLanguages = B.ToolPtr->InputLanguages();
+    for (StrVector::const_iterator B = InputLanguages.begin(),
+           E = InputLanguages.end(); B != E; ++B)
+      ToolsMap[*B].push_back(IntrusiveRefCntPtr<Edge>(Edg));
+    NodesMap["root"].AddEdge(Edg);
   }
   else {
     Node& N = getNode(A);
-    N.AddEdge(E);
+    N.AddEdge(Edg);
   }
   // Increase the inward edge counter.
   B.IncrInEdges();
@@ -381,10 +383,23 @@
 
     template<typename EdgeIter>
     static std::string getEdgeSourceLabel(const Node* N, EdgeIter I) {
-      if (N->ToolPtr)
+      if (N->ToolPtr) {
         return N->ToolPtr->OutputLanguage();
-      else
-        return I->ToolPtr->InputLanguage();
+      }
+      else {
+        const StrVector& InputLanguages = I->ToolPtr->InputLanguages();
+        std::string ret;
+
+        for (StrVector::const_iterator B = InputLanguages.begin(),
+               E = InputLanguages.end(); B != E; ++B) {
+          if (llvm::next(B) != E)
+            ret += *B + ", ";
+          else
+            ret += *B;
+        }
+
+        return ret;
+      }
     }
   };
 

Modified: llvm/trunk/tools/llvmc2/Tool.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Tool.h?rev=51742&r1=51741&r2=51742&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Tool.h (original)
+++ llvm/trunk/tools/llvmc2/Tool.h Fri May 30 01:18:16 2008
@@ -43,7 +43,7 @@
                                    const InputLanguagesSet& InLangs) const = 0;
 
     virtual const char* Name() const = 0;
-    virtual const char* InputLanguage() const = 0;
+    virtual StrVector InputLanguages() const = 0;
     virtual const char* OutputLanguage() const = 0;
     virtual const char* OutputSuffix() const = 0;
 

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

==============================================================================
--- llvm/trunk/tools/llvmc2/examples/Clang.td (original)
+++ llvm/trunk/tools/llvmc2/examples/Clang.td Fri May 30 01:18:16 2008
@@ -4,12 +4,8 @@
 
 include "Common.td"
 
-// TOFIX: It should be possible to use a string list in the 'in_language'
-// tool property. There should be also an 'in_language' test in the
-// 'case' construct.
-
 def clang : Tool<
-[(in_language "c"),
+[(in_language ["c", "c++", "objective-c"]),
  (out_language "llvm-bitcode"),
  (output_suffix "bc"),
  (cmd_line (case (switch_on "E"), "clang -E $INFILE -o $OUTFILE",

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

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Fri May 30 01:18:16 2008
@@ -18,6 +18,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Streams.h"
 
 #include <algorithm>
@@ -53,17 +54,22 @@
 //===----------------------------------------------------------------------===//
 /// Helper functions
 
+int InitPtrToInt(const Init* ptr) {
+  const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
+  return val.getValue();
+}
+
 const std::string& InitPtrToString(const Init* ptr) {
   const StringInit& val = dynamic_cast<const StringInit&>(*ptr);
   return val.getValue();
 }
 
-int InitPtrToInt(const Init* ptr) {
-  const IntInit& val = dynamic_cast<const IntInit&>(*ptr);
-  return val.getValue();
+const ListInit& InitPtrToList(const Init* ptr) {
+  const ListInit& val = dynamic_cast<const ListInit&>(*ptr);
+  return val;
 }
 
-const DagInit& InitPtrToDagInitRef(const Init* ptr) {
+const DagInit& InitPtrToDag(const Init* ptr) {
   const DagInit& val = dynamic_cast<const DagInit&>(*ptr);
   return val;
 }
@@ -308,7 +314,7 @@
 struct ToolProperties : public RefCountedBase<ToolProperties> {
   std::string Name;
   Init* CmdLine;
-  std::string InLanguage;
+  StrVector InLanguage;
   std::string OutLanguage;
   std::string OutputSuffix;
   unsigned Flags;
@@ -412,7 +418,7 @@
   /// operator() - Gets called for every tool property; Just forwards
   /// to the corresponding property handler.
   void operator() (Init* i) {
-    const DagInit& d = InitPtrToDagInitRef(i);
+    const DagInit& d = InitPtrToDag(i);
     const std::string& property_name = d.getOperator()->getAsString();
     PropertyHandlerMap::iterator method
       = propertyHandlers_.find(property_name);
@@ -439,7 +445,29 @@
 
   void onInLanguage (const DagInit* d) {
     checkNumberOfArguments(d, 1);
-    toolProps_.InLanguage = InitPtrToString(d->getArg(0));
+    Init* arg = d->getArg(0);
+
+    // Find out the argument's type.
+    if (typeid(*arg) == typeid(StringInit)) {
+      // It's a string.
+      toolProps_.InLanguage.push_back(InitPtrToString(arg));
+    }
+    else {
+      // It's a list.
+      const ListInit& lst = InitPtrToList(arg);
+      StrVector& out = toolProps_.InLanguage;
+
+      // Copy strings to the output vector.
+      for (ListInit::const_iterator B = lst.begin(), E = lst.end();
+           B != E; ++B) {
+        out.push_back(InitPtrToString(*B));
+      }
+
+      // Remove duplicates.
+      std::sort(out.begin(), out.end());
+      StrVector::iterator newE = std::unique(out.begin(), out.end());
+      out.erase(newE, out.end());
+    }
   }
 
   void onJoin (const DagInit* d) {
@@ -573,7 +601,7 @@
 
     for (unsigned B = 1, E = d->getNumArgs(); B!=E; ++B) {
       const DagInit& option_property
-        = InitPtrToDagInitRef(d->getArg(B));
+        = InitPtrToDag(d->getArg(B));
       const std::string& option_property_name
         = option_property.getOperator()->getAsString();
       OptionPropertyHandlerMap::iterator method
@@ -691,7 +719,7 @@
                               std::ostream& O) {
   O << '(';
   for (unsigned j = 0, NumArgs = d.getNumArgs(); j < NumArgs; ++j) {
-    const DagInit& InnerTest = InitPtrToDagInitRef(d.getArg(j));
+    const DagInit& InnerTest = InitPtrToDag(d.getArg(j));
     EmitCaseTest(InnerTest, IndentLevel, OptDescs, O);
     if (j != NumArgs - 1)
       O << ")\n" << IndentLevel << Indent1 << ' ' << LogicOp << " (";
@@ -736,7 +764,7 @@
       + d->getAsString();
 
   for (unsigned i = 0; i != numArgs; ++i) {
-    const DagInit& Test = InitPtrToDagInitRef(d->getArg(i));
+    const DagInit& Test = InitPtrToDag(d->getArg(i));
 
     // Emit the test.
     if (Test.getOperator()->getAsString() == "default") {
@@ -996,7 +1024,7 @@
   if (typeid(*P.CmdLine) == typeid(StringInit))
     EmitCmdLineVecFill(P.CmdLine, P.Name, Version, Indent2, O);
   else
-    EmitCaseConstructHandler(&InitPtrToDagInitRef(P.CmdLine), Indent2,
+    EmitCaseConstructHandler(&InitPtrToDag(P.CmdLine), Indent2,
                              EmitCmdLineVecFillCallback(Version, P.Name),
                              true, OptDescs, O);
 
@@ -1061,8 +1089,15 @@
 /// EmitInOutLanguageMethods - Emit the [Input,Output]Language()
 /// methods for a given Tool class.
 void EmitInOutLanguageMethods (const ToolProperties& P, std::ostream& O) {
-  O << Indent1 << "const char* InputLanguage() const {\n"
-    << Indent2 << "return \"" << P.InLanguage << "\";\n"
+  O << Indent1 << "StrVector InputLanguages() const {\n"
+    << Indent2 << "StrVector ret;\n";
+
+  for (StrVector::const_iterator B = P.InLanguage.begin(),
+         E = P.InLanguage.end(); B != E; ++B) {
+    O << Indent2 << "ret.push_back(\"" << *B << "\");\n";
+  }
+
+  O << Indent2 << "return ret;\n"
     << Indent1 << "}\n\n";
 
   O << Indent1 << "const char* OutputLanguage() const {\n"
@@ -1207,41 +1242,47 @@
 /// FillInToolToLang - Fills in two tables that map tool names to
 /// (input, output) languages.  Used by the typechecker.
 void FillInToolToLang (const ToolPropertiesList& TPList,
-                       StringMap<std::string>& ToolToInLang,
+                       StringMap<StringSet<> >& ToolToInLang,
                        StringMap<std::string>& ToolToOutLang) {
   for (ToolPropertiesList::const_iterator B = TPList.begin(), E = TPList.end();
        B != E; ++B) {
     const ToolProperties& P = *(*B);
-    ToolToInLang[P.Name] = P.InLanguage;
+    for (StrVector::const_iterator B = P.InLanguage.begin(),
+           E = P.InLanguage.end(); B != E; ++B)
+      ToolToInLang[P.Name].insert(*B);
     ToolToOutLang[P.Name] = P.OutLanguage;
   }
 }
 
 /// TypecheckGraph - Check that names for output and input languages
 /// on all edges do match.
-// TOFIX: check for cycles.
-// TOFIX: check for multiple default edges.
+// 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
+// sofisticated. Algorithms like these should be run on a real graph
+// instead of AST.
 void TypecheckGraph (Record* CompilationGraph,
                      const ToolPropertiesList& TPList) {
-  StringMap<std::string> ToolToInLang;
+  StringMap<StringSet<> > ToolToInLang;
   StringMap<std::string> ToolToOutLang;
 
   FillInToolToLang(TPList, ToolToInLang, ToolToOutLang);
   ListInit* edges = CompilationGraph->getValueAsListInit("edges");
-  StringMap<std::string>::iterator IAE = ToolToInLang.end();
-  StringMap<std::string>::iterator IBE = ToolToOutLang.end();
+  StringMap<std::string>::iterator IAE = ToolToOutLang.end();
+  StringMap<StringSet<> >::iterator IBE = ToolToInLang.end();
 
   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<std::string>::iterator IB = ToolToInLang.find(B->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" && IA->second != IB->second)
+    if (A->getName() != "root" && IB->second.count(IA->second) == 0)
       throw "Edge " + A->getName() + "->" + B->getName()
         + ": output->input language mismatch";
     if (B->getName() == "root")
@@ -1253,7 +1294,7 @@
 /// by EmitEdgeClass().
 void IncDecWeight (const Init* i, const char* IndentLevel,
                    std::ostream& O) {
-  const DagInit& d = InitPtrToDagInitRef(i);
+  const DagInit& d = InitPtrToDag(i);
   const std::string& OpName = d.getOperator()->getAsString();
 
   if (OpName == "inc_weight")
@@ -1389,7 +1430,7 @@
     }
     else {
       // This is a 'case' construct.
-      const DagInit& d = InitPtrToDagInitRef(P.CmdLine);
+      const DagInit& d = InitPtrToDag(P.CmdLine);
       bool even = false;
       for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end();
            B != E; ++B) {





More information about the llvm-commits mailing list