mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 14:40:25 +00:00
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
This commit is contained in:
parent
ecbdcf2ae0
commit
35a85e8453
@ -1,6 +1,5 @@
|
||||
// Check that we can compile files of different types together.
|
||||
// TOFIX: compiling files with same names should work.
|
||||
// RUN: llvmc2 %s %p/together1.c -o %t
|
||||
// RUN: llvmc2 %s %p/together.c -o %t
|
||||
// RUN: ./%t | grep hello
|
||||
|
||||
extern "C" void test();
|
||||
|
@ -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]);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
]>;
|
||||
|
@ -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"]>
|
||||
]>;
|
||||
|
Loading…
Reference in New Issue
Block a user