summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMikhail Glushenkov <foldr@codedgers.com>2008-05-06 18:10:20 +0000
committerMikhail Glushenkov <foldr@codedgers.com>2008-05-06 18:10:20 +0000
commit35a85e845302802be5191dd5c75ccea9eedea1be (patch)
treedc30ab9b1c857d5d33709c67a5fca6c812981f06 /tools
parentecbdcf2ae056404cde449783a1ec8ba798c36562 (diff)
downloadllvm-35a85e845302802be5191dd5c75ccea9eedea1be.tar.gz
llvm-35a85e845302802be5191dd5c75ccea9eedea1be.tar.bz2
llvm-35a85e845302802be5191dd5c75ccea9eedea1be.tar.xz
Take object file as input and handle files with the same name correctly.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50749 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/llvmc2/Action.cpp2
-rw-r--r--tools/llvmc2/CompilationGraph.cpp57
-rw-r--r--tools/llvmc2/CompilationGraph.h29
-rw-r--r--tools/llvmc2/Example.td4
-rw-r--r--tools/llvmc2/Tools.td14
5 files changed, 59 insertions, 47 deletions
diff --git a/tools/llvmc2/Action.cpp b/tools/llvmc2/Action.cpp
index fdbfb88611..3d61d37368 100644
--- a/tools/llvmc2/Action.cpp
+++ b/tools/llvmc2/Action.cpp
@@ -34,6 +34,7 @@ namespace {
if (!prog.canExecute())
throw std::runtime_error("Program '" + name + "' is not executable.");
+ // Build the command line vector and redirects.
const sys::Path* redirects[3] = {0,0,0};
sys::Path stdout_redirect;
@@ -54,6 +55,7 @@ namespace {
}
argv.push_back(0); // null terminate list.
+ // Invoke the program.
return sys::Program::ExecuteAndWait(prog, &argv[0], 0, &redirects[0]);
}
diff --git a/tools/llvmc2/CompilationGraph.cpp b/tools/llvmc2/CompilationGraph.cpp
index 817e0fb4c6..ed03f5856e 100644
--- a/tools/llvmc2/CompilationGraph.cpp
+++ b/tools/llvmc2/CompilationGraph.cpp
@@ -121,42 +121,50 @@ void CompilationGraph::insertEdge(const std::string& A, Edge* E) {
B.IncrInEdges();
}
+// Make a temporary file named like BaseName-RandomDigits.Suffix
+sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName,
+ const std::string& Suffix) {
+ sys::Path Out = TempDir;
+ Out.appendComponent(BaseName);
+ Out.appendSuffix(Suffix);
+ Out.makeUnique(true, NULL);
+ Out.eraseFromDisk();
+ return Out;
+}
+
// Pass input file through the chain until we bump into a Join node or
// a node that says that it is the last.
-const JoinTool*
-CompilationGraph::PassThroughGraph (sys::Path& In,
- const Node* StartNode,
- const sys::Path& TempDir) const {
+void CompilationGraph::PassThroughGraph (const sys::Path& InFile,
+ const Node* StartNode,
+ const sys::Path& TempDir) const {
bool Last = false;
+ sys::Path In = InFile;
const Node* CurNode = StartNode;
- JoinTool* ret = 0;
while(!Last) {
sys::Path Out;
Tool* CurTool = CurNode->ToolPtr.getPtr();
if (CurTool->IsJoin()) {
- ret = &dynamic_cast<JoinTool&>(*CurTool);
- ret->AddToJoinList(In);
+ JoinTool& JT = dynamic_cast<JoinTool&>(*CurTool);
+ JT.AddToJoinList(In);
break;
}
- // Is this the last tool?
+ // Since toolchains do not have to end with a Join node, we should
+ // check if this Node is the last.
if (!CurNode->HasChildren() || CurTool->IsLast()) {
- // Check if the first tool is also the last
- if (Out.empty())
+ if (!OutputFilename.empty()) {
+ Out.set(OutputFilename);
+ }
+ else {
Out.set(In.getBasename());
- else
- Out.appendComponent(In.getBasename());
- Out.appendSuffix(CurTool->OutputSuffix());
+ Out.appendSuffix(CurTool->OutputSuffix());
+ }
Last = true;
}
else {
- Out = TempDir;
- Out.appendComponent(In.getBasename());
- Out.appendSuffix(CurTool->OutputSuffix());
- Out.makeUnique(true, NULL);
- Out.eraseFromDisk();
+ Out = MakeTempFile(TempDir, In.getBasename(), CurTool->OutputSuffix());
}
if (CurTool->GenerateAction(In, Out).Execute() != 0)
@@ -166,8 +174,6 @@ CompilationGraph::PassThroughGraph (sys::Path& In,
CurNode->Name())->ToolName());
In = Out; Out.clear();
}
-
- return ret;
}
// Sort the nodes in topological order.
@@ -215,7 +221,6 @@ const Node* CompilationGraph::FindToolChain(const sys::Path& In) const {
return &getNode(ChooseEdge(TV)->ToolName());
}
-// TOFIX: merge some parts with PassThroughGraph.
// Build the targets. Command-line options are passed through
// temporary variables.
int CompilationGraph::Build (const sys::Path& TempDir) {
@@ -243,10 +248,12 @@ int CompilationGraph::Build (const sys::Path& TempDir) {
JoinTool* JT = &dynamic_cast<JoinTool&>(*CurNode->ToolPtr.getPtr());
bool IsLast = false;
- // Has files pending?
+ // Are there any files to be joined?
if (JT->JoinListEmpty())
continue;
+ // Is this the last tool in the chain?
+ // NOTE: we can process several chains in parallel.
if (!CurNode->HasChildren() || JT->IsLast()) {
if (OutputFilename.empty()) {
Out.set("a");
@@ -257,11 +264,7 @@ int CompilationGraph::Build (const sys::Path& TempDir) {
IsLast = true;
}
else {
- Out = TempDir;
- Out.appendComponent("tmp");
- Out.appendSuffix(JT->OutputSuffix());
- Out.makeUnique(true, NULL);
- Out.eraseFromDisk();
+ Out = MakeTempFile(TempDir, "tmp", JT->OutputSuffix());
}
if (JT->GenerateAction(Out).Execute() != 0)
diff --git a/tools/llvmc2/CompilationGraph.h b/tools/llvmc2/CompilationGraph.h
index 7d949e6d4f..72cde9a9e2 100644
--- a/tools/llvmc2/CompilationGraph.h
+++ b/tools/llvmc2/CompilationGraph.h
@@ -28,7 +28,7 @@
namespace llvmc {
- // An edge in the graph.
+ // An edge of the compilation graph.
class Edge : public llvm::RefCountedBaseVPTR<Edge> {
public:
Edge(const std::string& T) : ToolName_(T) {}
@@ -41,7 +41,7 @@ namespace llvmc {
std::string ToolName_;
};
- // Edges with no properties are instances of this class.
+ // Edges that have no properties are instances of this class.
class SimpleEdge : public Edge {
public:
SimpleEdge(const std::string& T) : Edge(T) {}
@@ -49,8 +49,9 @@ namespace llvmc {
bool isDefault() const { return true;}
};
- // A node in the graph.
+ // A node of the compilation graph.
struct Node {
+ // A Node holds a list of the outward edges.
typedef llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> container_type;
typedef container_type::iterator iterator;
typedef container_type::const_iterator const_iterator;
@@ -74,10 +75,9 @@ namespace llvmc {
void AddEdge(Edge* E)
{ OutEdges.push_back(llvm::IntrusiveRefCntPtr<Edge>(E)); }
- // Inward edge counter. Used by Build() to implement topological
- // sort.
- // TOTHINK: Move the counter back into Tool classes? Makes us more
- // const-correct.
+ // Inward edge counter. Used to implement topological sort.
+ // TOTHINK: Move the mutable counter back into Tool classes? Makes
+ // us more const-correct.
void IncrInEdges() { ++InEdges; }
void DecrInEdges() { --InEdges; }
bool HasNoInEdges() const { return InEdges == 0; }
@@ -85,11 +85,12 @@ namespace llvmc {
// Needed to implement NodeChildIterator/GraphTraits
CompilationGraph* OwningGraph;
// The corresponding Tool.
- // WARNING: For the root node, ToolPtr is NULL.
+ // WARNING: ToolPtr can be NULL (for the root node).
llvm::IntrusiveRefCntPtr<Tool> ToolPtr;
// Links to children.
container_type OutEdges;
- // Number of parents. Used for topological sorting.
+ // Inward edge counter. Updated in
+ // CompilationGraph::insertEdge(). Used for topological sorting.
unsigned InEdges;
};
@@ -99,8 +100,9 @@ namespace llvmc {
class CompilationGraph {
// Main data structure.
typedef llvm::StringMap<Node> nodes_map_type;
- // These are used to map from language names-> tools. (We can have
- // several tools associated with each language name.)
+ // These are used to map from language names to tools. (We can
+ // have several tools associated with each language name, hence
+ // the need for a vector of Edges.)
typedef
llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> tools_vector_type;
typedef llvm::StringMap<tools_vector_type> tools_map_type;
@@ -159,9 +161,8 @@ namespace llvmc {
const tools_vector_type& getToolsVector(const std::string& LangName) const;
// Pass the input file through the toolchain.
- const JoinTool* PassThroughGraph (llvm::sys::Path& In,
- const Node* StartNode,
- const llvm::sys::Path& TempDir) const;
+ void PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode,
+ 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;
diff --git a/tools/llvmc2/Example.td b/tools/llvmc2/Example.td
index 82d9da1515..57629904d1 100644
--- a/tools/llvmc2/Example.td
+++ b/tools/llvmc2/Example.td
@@ -32,5 +32,7 @@ def CompilationGraph : CompilationGraph<[
Edge<opt, llc>,
Edge<llc, llvm_gcc_assembler>,
- Edge<llvm_gcc_assembler, llvm_gcc_linker>
+ Edge<llvm_gcc_assembler, llvm_gcc_linker>,
+
+ Edge<root, llvm_gcc_linker>
]>;
diff --git a/tools/llvmc2/Tools.td b/tools/llvmc2/Tools.td
index 67104ec2c7..64c59ffdea 100644
--- a/tools/llvmc2/Tools.td
+++ b/tools/llvmc2/Tools.td
@@ -11,19 +11,21 @@
//
//===----------------------------------------------------------------------===//
-// Open issue: should we use DAG lists in Tool specifications
+// TOTHINK: Open issue: should we use DAG lists in Tool specifications
// or change to something like
+
// def LLVMGccC : < Tool<
// [ InLanguage<"c">,
// PrefixListOption<"Wl", [UnpackValues, PropertyName<Arg>, ...]>
// ...] ?
+
// DAG lists look more aesthetically pleasing to me.
def llvm_gcc_c : Tool<
[(in_language "c"),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line "llvm-gcc -c $INFILE -o $OUTFILE -emit-llvm"),
+ (cmd_line "llvm-gcc -c -x c $INFILE -o $OUTFILE -emit-llvm"),
(sink)
]>;
@@ -31,7 +33,7 @@ def llvm_gcc_cpp : Tool<
[(in_language "c++"),
(out_language "llvm-bitcode"),
(output_suffix "bc"),
- (cmd_line "llvm-g++ -c $INFILE -o $OUTFILE -emit-llvm"),
+ (cmd_line "llvm-g++ -c -x c++ $INFILE -o $OUTFILE -emit-llvm"),
(sink)
]>;
@@ -61,7 +63,8 @@ def llvm_gcc_assembler : Tool<
[(in_language "assembler"),
(out_language "object-code"),
(output_suffix "o"),
- (cmd_line "llvm-gcc -c $INFILE -o $OUTFILE"),
+ (cmd_line "llvm-gcc -c -x assembler $INFILE -o $OUTFILE"),
+ (switch_option "c", (stop_compilation)),
(prefix_list_option "Wa", (unpack_values), (help "pass options to assembler"))
]>;
@@ -85,4 +88,5 @@ def LanguageMap : LanguageMap<
LangToSuffixes<"llvm-assembler", ["ll"]>,
LangToSuffixes<"llvm-bitcode", ["bc"]>,
LangToSuffixes<"object-code", ["o"]>,
- LangToSuffixes<"executable", ["out"]>]>;
+ LangToSuffixes<"executable", ["out"]>
+ ]>;