llvm.org GIT mirror llvm / d752c3f
More work on edge properties. Use Edge classes instead of strings in CompilationGraph. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50726 91177308-0d34-0410-b5e6-96231b3b80d8 Mikhail Glushenkov 11 years ago
6 changed file(s) with 75 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
4949 def switch_on;
5050 def parameter_equals;
5151 def element_in_list;
52
53 // Property combinators
54 // TOFIX: implement
55 def and;
5652 def or;
5753
5854 // Map from suffixes to language names
3131 Node& CompilationGraph::getNode(const std::string& ToolName) {
3232 nodes_map_type::iterator I = NodesMap.find(ToolName);
3333 if (I == NodesMap.end())
34 throw std::runtime_error("Node " + ToolName + " is not in graph");
34 throw std::runtime_error("Node " + ToolName + " is not in the graph");
3535 return I->second;
3636 }
3737
3838 const Node& CompilationGraph::getNode(const std::string& ToolName) const {
3939 nodes_map_type::const_iterator I = NodesMap.find(ToolName);
4040 if (I == NodesMap.end())
41 throw std::runtime_error("Node " + ToolName + " is not in graph!");
41 throw std::runtime_error("Node " + ToolName + " is not in the graph!");
4242 return I->second;
4343 }
4444
6868 }
6969 }
7070
71 void CompilationGraph::insertEdge(const std::string& A,
72 const std::string& B) {
73 // TOTHINK: check this at compile-time?
74 if (B == "root")
75 throw std::runtime_error("Edges back to the root are not allowed!"
76 "Compilation graph should be acyclic!");
77
71 void CompilationGraph::insertEdge(const std::string& A, Edge* E) {
7872 if (A == "root") {
79 const Node& N = getNode(B);
73 const Node& N = getNode(E->ToolName());
8074 const std::string& InputLanguage = N.ToolPtr->InputLanguage();
81 ToolsMap[InputLanguage].push_back(B);
75 ToolsMap[InputLanguage].push_back(E->ToolName());
8276
8377 // Needed to support iteration via GraphTraits.
84 NodesMap["root"].AddEdge(new DefaultEdge(B));
78 NodesMap["root"].AddEdge(E);
8579 }
8680 else {
8781 Node& N = getNode(A);
88 // Check that there is a node at B.
89 getNode(B);
90 N.AddEdge(new DefaultEdge(B));
82 N.AddEdge(E);
9183 }
9284 }
9385
94 // TOFIX: extend, add an ability to choose between different
95 // toolchains, support more interesting graph topologies.
86 // TOFIX: support edge properties.
87 // TOFIX: support more interesting graph topologies.
9688 int CompilationGraph::Build (const sys::Path& tempDir) const {
9789 PathVector JoinList;
9890 const Tool* JoinTool = 0;
123115
124116 // Is this the last tool?
125117 if (!N->HasChildren() || CurTool->IsLast()) {
126 Out.appendComponent(In.getBasename());
118 // Check if the first tool is also the last
119 if(Out.empty())
120 Out.set(In.getBasename());
121 else
122 Out.appendComponent(In.getBasename());
127123 Out.appendSuffix(CurTool->OutputSuffix());
128124 Last = true;
129125 }
190186 }
191187
192188 void CompilationGraph::viewGraph() {
193 llvm::ViewGraph(this, "CompilationGraph");
189 llvm::ViewGraph(this, "compilation-graph");
194190 }
2727
2828 namespace llvmcc {
2929
30 // An edge in the graph.
3031 class Edge : public llvm::RefCountedBaseVPTR {
3132 public:
3233 Edge(const std::string& T) : ToolName_(T) {}
3940 std::string ToolName_;
4041 };
4142
42 class DefaultEdge : public Edge {
43 public:
44 DefaultEdge(const std::string& T) : Edge(T) {}
43 // Edges with no properties are instances of this class.
44 class SimpleEdge : public Edge {
45 public:
46 SimpleEdge(const std::string& T) : Edge(T) {}
4547 bool isEnabled() const { return true;}
4648 bool isDefault() const { return true;}
4749 };
4850
51 // A node in the graph.
4952 struct Node {
5053 typedef llvm::SmallVector, 3> container_type;
5154 typedef container_type::iterator iterator;
5558 Node(CompilationGraph* G) : OwningGraph(G) {}
5659 Node(CompilationGraph* G, Tool* T) : OwningGraph(G), ToolPtr(T) {}
5760
58 bool HasChildren() const { return OutEdges.empty(); }
61 bool HasChildren() const { return !OutEdges.empty(); }
5962
6063 iterator EdgesBegin() { return OutEdges.begin(); }
6164 const_iterator EdgesBegin() const { return OutEdges.begin(); }
6265 iterator EdgesEnd() { return OutEdges.end(); }
6366 const_iterator EdgesEnd() const { return OutEdges.end(); }
6467
65 // E is a new-allocated pointer.
68 // Takes ownership of the object.
6669 void AddEdge(Edge* E)
6770 { OutEdges.push_back(llvm::IntrusiveRefCntPtr(E)); }
6871
9295
9396 CompilationGraph();
9497
95 // insertVertex - insert a new node into the graph.
98 // insertVertex - insert a new node into the graph. Takes
99 // ownership of the object.
96100 void insertNode(Tool* T);
97101
98 // insertEdge - Insert a new edge into the graph. This function
99 // assumes that both A and B have been already inserted.
100 void insertEdge(const std::string& A, const std::string& B);
101
102 // Build - Build the target(s) from the set of the input
103 // files. Command-line options are passed implicitly as global
104 // variables.
102 // insertEdge - Insert a new edge into the graph. Takes ownership
103 // of the object.
104 void insertEdge(const std::string& A, Edge* E);
105
106 // Build - Build target(s) from the input file set. Command-line
107 // options are passed implicitly as global variables.
105108 int Build(llvm::sys::Path const& tempDir) const;
106109
107110 // Return a reference to the node correponding to the given tool
2020 Edge,
2121 Edge,
2222 Edge,
23
2324 Edge,
2425 Edge,
2526 Edge,
27
28 OptionalEdge,
29 OptionalEdge,
30 OptionalEdge,
31 OptionalEdge,
32
2633 Edge,
2734 Edge
2835 ]>;
1313
1414 include $(LEVEL)/Makefile.common
1515
16 TOOLS_TARGET=default
17 ifeq ($(TOOLS_TARGET), default)
18 TOOLS_SOURCE=Example.td
19 else
20 TOOLS_SOURCE=ExampleWithOpt.td
21 endif
16 TOOLS_SOURCE=Example.td
2217
2318 # TOFIX: integrate this part into Makefile.rules?
2419 # The degree of horrorshowness in that file is too much for me atm.
865865 }
866866
867867 // Check that all output and input language names match.
868 // TOFIX: check for cycles.
869 // TOFIX: check for multiple default edges.
868870 void TypecheckGraph (Record* CompilationGraph,
869871 const ToolPropertiesList& TPList) {
870872 StringMap ToolToInLang;
888890 if(A->getName() != "root" && IA->second != IB->second)
889891 throw "Edge " + A->getName() + "->" + B->getName()
890892 + ": output->input language mismatch";
891 }
892 }
893
894 // Emit Edge* classes used for.
893 if(B->getName() == "root")
894 throw std::string("Edges back to the root are not allowed!");
895 }
896 }
897
898 // Emit Edge* classes that represent edges in the graph.
899 // TOFIX: add edge properties.
895900 void EmitEdgeClasses (Record* CompilationGraph,
896901 const GlobalOptionDescriptions& OptDescs,
897902 std::ostream& O) {
898903 ListInit* edges = CompilationGraph->getValueAsListInit("edges");
899904
900905 for (unsigned i = 0; i < edges->size(); ++i) {
901 //Record* Edge = edges->getElementAsRecord(i);
902 //Record* A = Edge->getValueAsDef("a");
903 //Record* B = Edge->getValueAsDef("b");
904 //ListInit* Props = Edge->getValueAsListInit("props");
905
906 O << "class Edge" << i << " {};\n\n";
906 Record* Edge = edges->getElementAsRecord(i);
907 Record* B = Edge->getValueAsDef("b");
908 ListInit* Props = Edge->getValueAsListInit("props");
909
910 if (Props->empty())
911 continue;
912
913 O << "class Edge" << i << ": public Edge {\n"
914 << "public:\n"
915 << Indent1 << "Edge" << i << "() : Edge(\"" << B->getName()
916 << "\") {}\n";
917
918 O << Indent1 << "bool isEnabled() const { return true; }\n";
919
920 O << Indent1 << "bool isDefault() const { return false; }\n";
921
922 O << "};\n\n";
907923 }
908924 }
909925
936952 Record* Edge = edges->getElementAsRecord(i);
937953 Record* A = Edge->getValueAsDef("a");
938954 Record* B = Edge->getValueAsDef("b");
939 O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", \""
940 << B->getName() << "\");\n";
955 ListInit* Props = Edge->getValueAsListInit("props");
956
957 O << Indent1 << "G.insertEdge(\"" << A->getName() << "\", ";
958
959 if (Props->empty())
960 O << "new SimpleEdge(\"" << B->getName() << "\")";
961 else
962 O << "new Edge" << i << "()";
963
964 O << ");\n";
941965 }
942966
943967 O << "}\n\n";