[llvm-commits] [llvm] r50759 - in /llvm/trunk: test/LLVMC/false.c test/LLVMC/hello.cpp tools/llvmc2/Common.td tools/llvmc2/CompilationGraph.cpp tools/llvmc2/CompilationGraph.h tools/llvmc2/Example.td utils/TableGen/LLVMCConfigurationEmitter.cpp

Mikhail Glushenkov foldr at codedgers.com
Tue May 6 11:15:12 PDT 2008


Author: foldr
Date: Tue May  6 13:15:12 2008
New Revision: 50759

URL: http://llvm.org/viewvc/llvm-project?rev=50759&view=rev
Log:
Use edge weights to choose the right linker based on input language names.

Modified:
    llvm/trunk/test/LLVMC/false.c
    llvm/trunk/test/LLVMC/hello.cpp
    llvm/trunk/tools/llvmc2/Common.td
    llvm/trunk/tools/llvmc2/CompilationGraph.cpp
    llvm/trunk/tools/llvmc2/CompilationGraph.h
    llvm/trunk/tools/llvmc2/Example.td
    llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp

Modified: llvm/trunk/test/LLVMC/false.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/false.c?rev=50759&r1=50758&r2=50759&view=diff

==============================================================================
--- llvm/trunk/test/LLVMC/false.c (original)
+++ llvm/trunk/test/LLVMC/false.c Tue May  6 13:15:12 2008
@@ -1,5 +1,5 @@
 // Test that we can compile .c files as C++ and vice versa
-// RUN: llvmc2 --linker=c++ -x c++ %s -x c %p/false.cpp -x lisp -x whatnot -x none %p/false2.cpp -o %t
+// RUN: llvmc2 -x c++ %s -x c %p/false.cpp -x lisp -x whatnot -x none %p/false2.cpp -o %t
 // RUN: ./%t | grep hello
 
 #include <iostream>

Modified: llvm/trunk/test/LLVMC/hello.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LLVMC/hello.cpp?rev=50759&r1=50758&r2=50759&view=diff

==============================================================================
--- llvm/trunk/test/LLVMC/hello.cpp (original)
+++ llvm/trunk/test/LLVMC/hello.cpp Tue May  6 13:15:12 2008
@@ -1,5 +1,5 @@
 // Test that we can compile C++ code.
-// RUN: llvmc2 --linker=c++ %s -o %t
+// RUN: llvmc2 %s -o %t
 // RUN: ./%t | grep hello
 #include <iostream>
 

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

==============================================================================
--- llvm/trunk/tools/llvmc2/Common.td (original)
+++ llvm/trunk/tools/llvmc2/Common.td Tue May  6 13:15:12 2008
@@ -50,7 +50,11 @@
 def switch_on;
 def parameter_equals;
 def element_in_list;
+def if_input_languages_contain;
+
+// Edge property combinators.
 def and;
+def or;
 
 // Map from suffixes to language names
 

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

==============================================================================
--- llvm/trunk/tools/llvmc2/CompilationGraph.cpp (original)
+++ llvm/trunk/tools/llvmc2/CompilationGraph.cpp Tue May  6 13:15:12 2008
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 #include <iterator>
+#include <iostream>
 #include <limits>
 #include <queue>
 #include <stdexcept>
@@ -36,6 +37,7 @@
   // Return the edge with the maximum weight.
   template <class C>
   const Edge* ChooseEdge(const C& EdgesContainer,
+                         const InputLanguagesSet& InLangs,
                          const std::string& NodeName = "root") {
     const Edge* MaxEdge = 0;
     unsigned MaxWeight = 0;
@@ -44,7 +46,7 @@
     for (typename C::const_iterator B = EdgesContainer.begin(),
            E = EdgesContainer.end(); B != E; ++B) {
       const Edge* E = B->getPtr();
-      unsigned EW = E->Weight();
+      unsigned EW = E->Weight(InLangs);
       if (EW > MaxWeight) {
         MaxEdge = E;
         MaxWeight = EW;
@@ -142,6 +144,7 @@
 // a node that says that it is the last.
 void CompilationGraph::PassThroughGraph (const sys::Path& InFile,
                                          const Node* StartNode,
+                                         const InputLanguagesSet& InLangs,
                                          const sys::Path& TempDir) const {
   bool Last = false;
   sys::Path In = InFile;
@@ -180,6 +183,7 @@
       return;
 
     CurNode = &getNode(ChooseEdge(CurNode->OutEdges,
+                                  InLangs,
                                   CurNode->Name())->ToolName());
     In = Out; Out.clear();
   }
@@ -221,21 +225,32 @@
 }
 
 // Find head of the toolchain corresponding to the given file.
+// Also, insert an input language into InLangs.
 const Node* CompilationGraph::
-FindToolChain(const sys::Path& In, const std::string* forceLanguage) const {
+FindToolChain(const sys::Path& In, const std::string* forceLanguage,
+              InputLanguagesSet& InLangs) const {
+
+  // Determine the input language.
   const std::string& InLanguage =
     forceLanguage ? *forceLanguage : getLanguage(In);
+
+  // Add the current input language to the input language set.
+  InLangs.insert(InLanguage);
+
+  // Find the toolchain for the input language.
   const tools_vector_type& TV = getToolsVector(InLanguage);
   if (TV.empty())
     throw std::runtime_error("No toolchain corresponding to language"
                              + InLanguage + " found!");
-  return &getNode(ChooseEdge(TV)->ToolName());
+  return &getNode(ChooseEdge(TV, InLangs)->ToolName());
 }
 
 // Build the targets. Command-line options are passed through
 // temporary variables.
 int CompilationGraph::Build (const sys::Path& TempDir) {
 
+  InputLanguagesSet InLangs;
+
   // This is related to -x option handling.
   cl::list<std::string>::const_iterator xIter = Languages.begin(),
     xBegin = xIter, xEnd = Languages.end();
@@ -284,9 +299,9 @@
     }
 
     // Find the toolchain corresponding to this file.
-    const Node* N = FindToolChain(In, xLanguage);
+    const Node* N = FindToolChain(In, xLanguage, InLangs);
     // Pass file through the chain starting at head.
-    PassThroughGraph(In, N, TempDir);
+    PassThroughGraph(In, N, InLangs, TempDir);
   }
 
   std::vector<const Node*> JTV;
@@ -324,9 +339,10 @@
       throw std::runtime_error("Tool returned error code!");
 
     if (!IsLast) {
-      const Node* NextNode = &getNode(ChooseEdge(CurNode->OutEdges,
-                                                 CurNode->Name())->ToolName());
-      PassThroughGraph(Out, NextNode, TempDir);
+      const Node* NextNode =
+        &getNode(ChooseEdge(CurNode->OutEdges, InLangs,
+                            CurNode->Name())->ToolName());
+      PassThroughGraph(Out, NextNode, InLangs, TempDir);
     }
   }
 

Modified: llvm/trunk/tools/llvmc2/CompilationGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/CompilationGraph.h?rev=50759&r1=50758&r2=50759&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/CompilationGraph.h (original)
+++ llvm/trunk/tools/llvmc2/CompilationGraph.h Tue May  6 13:15:12 2008
@@ -20,14 +20,18 @@
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/iterator"
+//#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/System/Path.h"
 
+#include <set>
 #include <string>
 
 namespace llvmc {
 
+  typedef std::set<std::string> InputLanguagesSet;
+
   // An edge of the compilation graph.
   class Edge : public llvm::RefCountedBaseVPTR<Edge> {
   public:
@@ -35,7 +39,7 @@
     virtual ~Edge() {};
 
     const std::string& ToolName() const { return ToolName_; }
-    virtual unsigned Weight() const = 0;
+    virtual unsigned Weight(const InputLanguagesSet& InLangs) const = 0;
   private:
     std::string ToolName_;
   };
@@ -44,7 +48,7 @@
   class SimpleEdge : public Edge {
   public:
     SimpleEdge(const std::string& T) : Edge(T) {}
-    unsigned Weight() const { return 1; }
+    unsigned Weight(const InputLanguagesSet&) const { return 1; }
   };
 
   // A node of the compilation graph.
@@ -160,11 +164,13 @@
 
     // Pass the input file through the toolchain.
     void PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode,
+                           const InputLanguagesSet& InLangs,
                            const llvm::sys::Path& TempDir) const;
 
     // Find head of the toolchain corresponding to the given file.
     const Node* FindToolChain(const llvm::sys::Path& In,
-                              const std::string* forceLanguage) const;
+                              const std::string* forceLanguage,
+                              InputLanguagesSet& InLangs) const;
 
     // Sort the nodes in topological order.
     void TopologicalSort(std::vector<const Node*>& Out);

Modified: llvm/trunk/tools/llvmc2/Example.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc2/Example.td?rev=50759&r1=50758&r2=50759&view=diff

==============================================================================
--- llvm/trunk/tools/llvmc2/Example.td (original)
+++ llvm/trunk/tools/llvmc2/Example.td Tue May  6 13:15:12 2008
@@ -34,12 +34,14 @@
     Edge<llc, llvm_gcc_assembler>,
     Edge<llvm_gcc_assembler, llvm_gcc_linker>,
     OptionalEdge<llvm_gcc_assembler, llvm_gcc_cpp_linker,
-                 [(parameter_equals "linker", "g++"),
-                  (parameter_equals "linker", "c++")]>,
+                 [(if_input_languages_contain "c++"),
+                  (or (parameter_equals "linker", "g++"),
+                      (parameter_equals "linker", "c++"))]>,
 
 
     Edge<root, llvm_gcc_linker>,
     OptionalEdge<root, llvm_gcc_cpp_linker,
-                 [(parameter_equals "linker", "g++"),
-                  (parameter_equals "linker", "c++")]>
+                 [(if_input_languages_contain "c++"),
+                  (or (parameter_equals "linker", "g++"),
+                      (parameter_equals "linker", "c++"))]>
     ]>;

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

==============================================================================
--- llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/LLVMCConfigurationEmitter.cpp Tue May  6 13:15:12 2008
@@ -911,19 +911,29 @@
 }
 
 // Helper function used by EmitEdgePropertyTest.
-void EmitEdgePropertyTest1Arg(const DagInit& Prop,
+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));
-  const GlobalOptionDescription& OptDesc = OptDescs.FindOption(OptName);
-  if (OptDesc.Type != OptionType::Switch)
-    throw OptName + ": incorrect option type!";
-  O << OptDesc.GenVariableName();
+  if (PropName == "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") {
+    O << "InLangs.count(\"" << OptName << "\") != 0";
+    return true;
+  }
+
+  return false;
 }
 
 // Helper function used by EmitEdgePropertyTest.
-void EmitEdgePropertyTest2Args(const std::string& PropName,
+bool EmitEdgePropertyTest2Args(const std::string& PropName,
                                const DagInit& Prop,
                                const GlobalOptionDescriptions& OptDescs,
                                std::ostream& O) {
@@ -937,6 +947,7 @@
         && OptDesc.Type != OptionType::Prefix)
       throw OptName + ": incorrect option type!";
     O << OptDesc.GenVariableName() << " == \"" << OptArg << "\"";
+    return true;
   }
   else if (PropName == "element_in_list") {
     if (OptDesc.Type != OptionType::ParameterList
@@ -946,9 +957,10 @@
     O << "std::find(" << VarName << ".begin(),\n"
       << Indent3 << VarName << ".end(), \""
       << OptArg << "\") != " << VarName << ".end()";
+    return true;
   }
-  else
-    throw PropName + ": unknown edge property!";
+
+  return false;
 }
 
 // Helper function used by EmitEdgeClass.
@@ -956,10 +968,29 @@
                           const DagInit& Prop,
                           const GlobalOptionDescriptions& OptDescs,
                           std::ostream& O) {
-  if (PropName == "switch_on")
-    EmitEdgePropertyTest1Arg(Prop, OptDescs, O);
+  if (EmitEdgePropertyTest1Arg(PropName, Prop, OptDescs, O))
+    return;
+  else if (EmitEdgePropertyTest2Args(PropName, Prop, OptDescs, O))
+    return;
   else
-    EmitEdgePropertyTest2Args(PropName, Prop, OptDescs, O);
+    throw PropName + ": unknown edge property!";
+}
+
+// Helper function used by EmitEdgeClass.
+void EmitLogicalOperationTest(const DagInit& Prop, const char* LogicOp,
+                              const GlobalOptionDescriptions& OptDescs,
+                              std::ostream& O) {
+  O << '(';
+  for (unsigned j = 0, NumArgs = Prop.getNumArgs(); j < NumArgs; ++j) {
+    const DagInit& InnerProp = dynamic_cast<DagInit&>(*Prop.getArg(j));
+    const std::string& InnerPropName =
+      InnerProp.getOperator()->getAsString();
+    EmitEdgePropertyTest(InnerPropName, InnerProp, OptDescs, O);
+    if (j != NumArgs - 1)
+      O << ")\n" << Indent3 << ' ' << LogicOp << " (";
+    else
+      O << ')';
+  }
 }
 
 // Emit a single Edge* class.
@@ -975,7 +1006,7 @@
     << "\") {}\n\n"
 
   // Function Weight().
-    << Indent1 << "unsigned Weight() const {\n"
+    << Indent1 << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n"
     << Indent2 << "unsigned ret = 0;\n";
 
   for (size_t i = 0, PropsSize = Props->size(); i < PropsSize; ++i) {
@@ -985,24 +1016,17 @@
     if (PropName == "default")
       IsDefault = true;
 
-    O << Indent2 << "if ((";
+    O << Indent2 << "if (";
     if (PropName == "and") {
-      O << '(';
-      for (unsigned j = 0, NumArgs = Prop.getNumArgs(); j < NumArgs; ++j) {
-        const DagInit& InnerProp = dynamic_cast<DagInit&>(*Prop.getArg(j));
-        const std::string& InnerPropName =
-          InnerProp.getOperator()->getAsString();
-        EmitEdgePropertyTest(InnerPropName, InnerProp, OptDescs, O);
-        if (j != NumArgs - 1)
-          O << ")\n" << Indent3 << " && (";
-        else
-          O << ')';
-      }
+      EmitLogicalOperationTest(Prop, "&&", OptDescs, O);
+    }
+    else if (PropName == "or") {
+      EmitLogicalOperationTest(Prop, "||", OptDescs, O);
     }
     else {
       EmitEdgePropertyTest(PropName, Prop, OptDescs, O);
     }
-    O << "))\n" << Indent3 << "ret += 2;\n";
+    O << ")\n" << Indent3 << "ret += 2;\n";
   }
 
   if (IsDefault)





More information about the llvm-commits mailing list