diff options
author | Mikhail Glushenkov <foldr@codedgers.com> | 2008-05-06 18:15:12 +0000 |
---|---|---|
committer | Mikhail Glushenkov <foldr@codedgers.com> | 2008-05-06 18:15:12 +0000 |
commit | 76b1b24dc805c7a3adb4517443241ed3ecd0ba74 (patch) | |
tree | bfd96d543fa856e4b4bf11a8d92a91a32a4e8556 /tools/llvmc2 | |
parent | bb8b58dcf3e1994beb458e777b306fa3805ee50f (diff) | |
download | external_llvm-76b1b24dc805c7a3adb4517443241ed3ecd0ba74.zip external_llvm-76b1b24dc805c7a3adb4517443241ed3ecd0ba74.tar.gz external_llvm-76b1b24dc805c7a3adb4517443241ed3ecd0ba74.tar.bz2 |
Use edge weights to choose the right linker based on input language names.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50759 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvmc2')
-rw-r--r-- | tools/llvmc2/Common.td | 4 | ||||
-rw-r--r-- | tools/llvmc2/CompilationGraph.cpp | 32 | ||||
-rw-r--r-- | tools/llvmc2/CompilationGraph.h | 12 | ||||
-rw-r--r-- | tools/llvmc2/Example.td | 10 |
4 files changed, 43 insertions, 15 deletions
diff --git a/tools/llvmc2/Common.td b/tools/llvmc2/Common.td index 5e25dcf..db28841 100644 --- a/tools/llvmc2/Common.td +++ b/tools/llvmc2/Common.td @@ -50,7 +50,11 @@ def required; 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 diff --git a/tools/llvmc2/CompilationGraph.cpp b/tools/llvmc2/CompilationGraph.cpp index 310413b..f5cefbf 100644 --- a/tools/llvmc2/CompilationGraph.cpp +++ b/tools/llvmc2/CompilationGraph.cpp @@ -20,6 +20,7 @@ #include <algorithm> #include <iterator> +#include <iostream> #include <limits> #include <queue> #include <stdexcept> @@ -36,6 +37,7 @@ namespace { // 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 @@ namespace { 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 @@ namespace { // 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 @@ void CompilationGraph::PassThroughGraph (const sys::Path& InFile, return; CurNode = &getNode(ChooseEdge(CurNode->OutEdges, + InLangs, CurNode->Name())->ToolName()); In = Out; Out.clear(); } @@ -221,21 +225,32 @@ TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out) { } // 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 @@ int CompilationGraph::Build (const sys::Path& TempDir) { } // 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 @@ int CompilationGraph::Build (const sys::Path& TempDir) { 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); } } diff --git a/tools/llvmc2/CompilationGraph.h b/tools/llvmc2/CompilationGraph.h index 3dc8bc0..1158d8d 100644 --- a/tools/llvmc2/CompilationGraph.h +++ b/tools/llvmc2/CompilationGraph.h @@ -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 @@ namespace llvmc { 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 @@ namespace llvmc { 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 @@ namespace llvmc { // 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); diff --git a/tools/llvmc2/Example.td b/tools/llvmc2/Example.td index 2270902..6fb998b 100644 --- a/tools/llvmc2/Example.td +++ b/tools/llvmc2/Example.td @@ -34,12 +34,14 @@ def CompilationGraph : CompilationGraph<[ 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++"))]> ]>; |