aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/llvmc2/Common.td4
-rw-r--r--tools/llvmc2/CompilationGraph.cpp34
-rw-r--r--tools/llvmc2/CompilationGraph.h25
-rw-r--r--tools/llvmc2/Example.td7
-rw-r--r--tools/llvmc2/Makefile7
-rw-r--r--utils/TableGen/LLVMCCConfigurationEmitter.cpp40
6 files changed, 69 insertions, 48 deletions
diff --git a/tools/llvmc2/Common.td b/tools/llvmc2/Common.td
index 4435857..30905a4 100644
--- a/tools/llvmc2/Common.td
+++ b/tools/llvmc2/Common.td
@@ -50,10 +50,6 @@ def required;
def switch_on;
def parameter_equals;
def element_in_list;
-
-// Property combinators
-// TOFIX: implement
-def and;
def or;
// Map from suffixes to language names
diff --git a/tools/llvmc2/CompilationGraph.cpp b/tools/llvmc2/CompilationGraph.cpp
index 07b09e7..77c5896 100644
--- a/tools/llvmc2/CompilationGraph.cpp
+++ b/tools/llvmc2/CompilationGraph.cpp
@@ -32,14 +32,14 @@ CompilationGraph::CompilationGraph() {
Node& CompilationGraph::getNode(const std::string& ToolName) {
nodes_map_type::iterator I = NodesMap.find(ToolName);
if (I == NodesMap.end())
- throw std::runtime_error("Node " + ToolName + " is not in graph");
+ throw std::runtime_error("Node " + ToolName + " is not in the graph");
return I->second;
}
const Node& CompilationGraph::getNode(const std::string& ToolName) const {
nodes_map_type::const_iterator I = NodesMap.find(ToolName);
if (I == NodesMap.end())
- throw std::runtime_error("Node " + ToolName + " is not in graph!");
+ throw std::runtime_error("Node " + ToolName + " is not in the graph!");
return I->second;
}
@@ -69,31 +69,23 @@ void CompilationGraph::insertNode(Tool* V) {
}
}
-void CompilationGraph::insertEdge(const std::string& A,
- const std::string& B) {
- // TOTHINK: check this at compile-time?
- if (B == "root")
- throw std::runtime_error("Edges back to the root are not allowed!"
- "Compilation graph should be acyclic!");
-
+void CompilationGraph::insertEdge(const std::string& A, Edge* E) {
if (A == "root") {
- const Node& N = getNode(B);
+ const Node& N = getNode(E->ToolName());
const std::string& InputLanguage = N.ToolPtr->InputLanguage();
- ToolsMap[InputLanguage].push_back(B);
+ ToolsMap[InputLanguage].push_back(E->ToolName());
// Needed to support iteration via GraphTraits.
- NodesMap["root"].AddEdge(new DefaultEdge(B));
+ NodesMap["root"].AddEdge(E);
}
else {
Node& N = getNode(A);
- // Check that there is a node at B.
- getNode(B);
- N.AddEdge(new DefaultEdge(B));
+ N.AddEdge(E);
}
}
-// TOFIX: extend, add an ability to choose between different
-// toolchains, support more interesting graph topologies.
+// TOFIX: support edge properties.
+// TOFIX: support more interesting graph topologies.
int CompilationGraph::Build (const sys::Path& tempDir) const {
PathVector JoinList;
const Tool* JoinTool = 0;
@@ -124,7 +116,11 @@ int CompilationGraph::Build (const sys::Path& tempDir) const {
// Is this the last tool?
if (!N->HasChildren() || CurTool->IsLast()) {
- Out.appendComponent(In.getBasename());
+ // Check if the first tool is also the last
+ if(Out.empty())
+ Out.set(In.getBasename());
+ else
+ Out.appendComponent(In.getBasename());
Out.appendSuffix(CurTool->OutputSuffix());
Last = true;
}
@@ -191,5 +187,5 @@ void CompilationGraph::writeGraph() {
}
void CompilationGraph::viewGraph() {
- llvm::ViewGraph(this, "CompilationGraph");
+ llvm::ViewGraph(this, "compilation-graph");
}
diff --git a/tools/llvmc2/CompilationGraph.h b/tools/llvmc2/CompilationGraph.h
index 85210dc..d953aee 100644
--- a/tools/llvmc2/CompilationGraph.h
+++ b/tools/llvmc2/CompilationGraph.h
@@ -28,6 +28,7 @@
namespace llvmcc {
+ // An edge in the graph.
class Edge : public llvm::RefCountedBaseVPTR<Edge> {
public:
Edge(const std::string& T) : ToolName_(T) {}
@@ -40,13 +41,15 @@ namespace llvmcc {
std::string ToolName_;
};
- class DefaultEdge : public Edge {
+ // Edges with no properties are instances of this class.
+ class SimpleEdge : public Edge {
public:
- DefaultEdge(const std::string& T) : Edge(T) {}
+ SimpleEdge(const std::string& T) : Edge(T) {}
bool isEnabled() const { return true;}
bool isDefault() const { return true;}
};
+ // A node in the graph.
struct Node {
typedef llvm::SmallVector<llvm::IntrusiveRefCntPtr<Edge>, 3> container_type;
typedef container_type::iterator iterator;
@@ -56,14 +59,14 @@ namespace llvmcc {
Node(CompilationGraph* G) : OwningGraph(G) {}
Node(CompilationGraph* G, Tool* T) : OwningGraph(G), ToolPtr(T) {}
- bool HasChildren() const { return OutEdges.empty(); }
+ bool HasChildren() const { return !OutEdges.empty(); }
iterator EdgesBegin() { return OutEdges.begin(); }
const_iterator EdgesBegin() const { return OutEdges.begin(); }
iterator EdgesEnd() { return OutEdges.end(); }
const_iterator EdgesEnd() const { return OutEdges.end(); }
- // E is a new-allocated pointer.
+ // Takes ownership of the object.
void AddEdge(Edge* E)
{ OutEdges.push_back(llvm::IntrusiveRefCntPtr<Edge>(E)); }
@@ -93,16 +96,16 @@ namespace llvmcc {
CompilationGraph();
- // insertVertex - insert a new node into the graph.
+ // insertVertex - insert a new node into the graph. Takes
+ // ownership of the object.
void insertNode(Tool* T);
- // insertEdge - Insert a new edge into the graph. This function
- // assumes that both A and B have been already inserted.
- void insertEdge(const std::string& A, const std::string& B);
+ // insertEdge - Insert a new edge into the graph. Takes ownership
+ // of the object.
+ void insertEdge(const std::string& A, Edge* E);
- // Build - Build the target(s) from the set of the input
- // files. Command-line options are passed implicitly as global
- // variables.
+ // Build - Build target(s) from the input file set. Command-line
+ // options are passed implicitly as global variables.
int Build(llvm::sys::Path const& tempDir) const;
// Return a reference to the node correponding to the given tool
diff --git a/tools/llvmc2/Example.td b/tools/llvmc2/Example.td
index d56f7f9..79376ef 100644
--- a/tools/llvmc2/Example.td
+++ b/tools/llvmc2/Example.td
@@ -21,9 +21,16 @@ def CompilationGraph : CompilationGraph<[
Edge<root, llvm_gcc_assembler>,
Edge<root, llvm_gcc_cpp>,
Edge<root, llvm_as>,
+
Edge<llvm_gcc_c, llc>,
Edge<llvm_gcc_cpp, llc>,
Edge<llvm_as, llc>,
+
+ OptionalEdge<llvm_gcc_c, opt, [(switch_on "opt")]>,
+ OptionalEdge<llvm_gcc_cpp, opt, [(switch_on "opt")]>,
+ OptionalEdge<llvm_as, opt, [(switch_on "opt")]>,
+ OptionalEdge<opt, llc, [(switch_on "opt")]>,
+
Edge<llc, llvm_gcc_assembler>,
Edge<llvm_gcc_assembler, llvm_gcc_linker>
]>;
diff --git a/tools/llvmc2/Makefile b/tools/llvmc2/Makefile
index 8fe1e81..4cb967c 100644
--- a/tools/llvmc2/Makefile
+++ b/tools/llvmc2/Makefile
@@ -14,12 +14,7 @@ REQUIRES_EH := 1
include $(LEVEL)/Makefile.common
-TOOLS_TARGET=default
-ifeq ($(TOOLS_TARGET), default)
- TOOLS_SOURCE=Example.td
-else
- TOOLS_SOURCE=ExampleWithOpt.td
-endif
+TOOLS_SOURCE=Example.td
# TOFIX: integrate this part into Makefile.rules?
# The degree of horrorshowness in that file is too much for me atm.
diff --git a/utils/TableGen/LLVMCCConfigurationEmitter.cpp b/utils/TableGen/LLVMCCConfigurationEmitter.cpp
index 92e2df1..606510e 100644
--- a/utils/TableGen/LLVMCCConfigurationEmitter.cpp
+++ b/utils/TableGen/LLVMCCConfigurationEmitter.cpp
@@ -866,6 +866,8 @@ void FillInToolToLang (const ToolPropertiesList& TPList,
}
// Check that all output and input language names match.
+// TOFIX: check for cycles.
+// TOFIX: check for multiple default edges.
void TypecheckGraph (Record* CompilationGraph,
const ToolPropertiesList& TPList) {
StringMap<std::string> ToolToInLang;
@@ -889,22 +891,36 @@ void TypecheckGraph (Record* CompilationGraph,
if(A->getName() != "root" && IA->second != IB->second)
throw "Edge " + A->getName() + "->" + B->getName()
+ ": output->input language mismatch";
+ if(B->getName() == "root")
+ throw std::string("Edges back to the root are not allowed!");
}
}
-// Emit Edge* classes used for.
+// Emit Edge* classes that represent edges in the graph.
+// TOFIX: add edge properties.
void EmitEdgeClasses (Record* CompilationGraph,
const GlobalOptionDescriptions& OptDescs,
std::ostream& O) {
ListInit* edges = CompilationGraph->getValueAsListInit("edges");
for (unsigned i = 0; i < edges->size(); ++i) {
- //Record* Edge = edges->getElementAsRecord(i);
- //Record* A = Edge->getValueAsDef("a");
- //Record* B = Edge->getValueAsDef("b");
- //ListInit* Props = Edge->getValueAsListInit("props");
+ Record* Edge = edges->getElementAsRecord(i);
+ Record* B = Edge->getValueAsDef("b");
+ ListInit* Props = Edge->getValueAsListInit("props");
+
+ if (Props->empty())
+ continue;
+
+ O << "class Edge" << i << ": public Edge {\n"
+ << "public:\n"
+ << Indent1 << "Edge" << i << "() : Edge(\"" << B->getName()
+ << "\") {}\n";
+
+ O << Indent1 << "bool isEnabled() const { return true; }\n";
- O << "class Edge" << i << " {};\n\n";
+ O << Indent1 << "bool isDefault() const { return false; }\n";
+
+ O << "};\n\n";
}
}
@@ -937,8 +953,16 @@ void EmitPopulateCompilationGraph (Record* CompilationGraph,
Record* Edge = edges->getElementAsRecord(i);
Record* A = Edge->getValueAsDef("a");
Record* B = Edge->getValueAsDef("b");
- O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", \""
- << B->getName() << "\");\n";
+ ListInit* Props = Edge->getValueAsListInit("props");
+
+ O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", ";
+
+ if (Props->empty())
+ O << "new SimpleEdge(\"" << B->getName() << "\")";
+ else
+ O << "new Edge" << i << "()";
+
+ O << ");\n";
}
O << "}\n\n";