summaryrefslogtreecommitdiff
path: root/tools/llvmc2/CompilationGraph.h
blob: f46b287bd5d6edd4fa91a91e46cdb41174e49ebd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
//===--- CompilationGraph.h - The LLVM Compiler Driver ----------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Compilation graph - definition.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H
#define LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H

#include "AutoGenerated.h"
#include "Tool.h"

#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/System/Path.h"

#include <string>

namespace llvmcc {

  class CompilationGraph;

  struct Node {
    typedef llvm::SmallVector<std::string, 3> sequence_type;

    Node() {}
    Node(CompilationGraph* G) : OwningGraph(G) {}
    Node(CompilationGraph* G, Tool* T) : OwningGraph(G), ToolPtr(T) {}

    // Needed to implement NodeChildIterator/GraphTraits
    CompilationGraph* OwningGraph;
    // The corresponding Tool.
    llvm::IntrusiveRefCntPtr<Tool> ToolPtr;
    // Links to children.
    sequence_type Children;
  };

  // This can be generalised to something like value_iterator for maps
  class NodesIterator : public llvm::StringMap<Node>::iterator {
    typedef llvm::StringMap<Node>::iterator super;
    typedef NodesIterator ThisType;
    typedef Node* pointer;
    typedef Node& reference;

  public:
    NodesIterator(super I) : super(I) {}

    inline reference operator*() const {
      return super::operator->()->second;
    }
    inline pointer operator->() const {
      return &super::operator->()->second;
    }
  };

  class CompilationGraph {
    typedef llvm::StringMap<Node> nodes_map_type;
    typedef llvm::SmallVector<std::string, 3> tools_vector_type;
    typedef llvm::StringMap<tools_vector_type> tools_map_type;

    // Map from file extensions to language names.
    LanguageMap ExtsToLangs;
    // Map from language names to lists of tool names.
    tools_map_type ToolsMap;
    // Map from tool names to Tool objects.
    nodes_map_type NodesMap;

  public:

    CompilationGraph();

    // insertVertex - insert a new node into the graph.
    void insertVertex(const llvm::IntrusiveRefCntPtr<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);

    // Build - Build the target(s) from the set of the input
    // files. Command-line options are passed implicitly as global
    // variables.
    int Build(llvm::sys::Path const& tempDir) const;

    /// viewGraph - This function is meant for use from the debugger.
    /// You can just say 'call G->viewGraph()' and a ghostview window
    /// should pop up from the program, displaying the compilation
    /// graph. This depends on there being a 'dot' and 'gv' program
    /// in your path.
    void viewGraph();

    /// Write a CompilationGraph.dot file.
    void writeGraph();

    // GraphTraits support

    typedef NodesIterator nodes_iterator;

    nodes_iterator nodes_begin() {
      return NodesIterator(NodesMap.begin());
    }

    nodes_iterator nodes_end() {
      return NodesIterator(NodesMap.end());
    }

    // Return a reference to the node correponding to the given tool
    // name. Throws std::runtime_error in case of error.
    Node& getNode(const std::string& ToolName);
    const Node& getNode(const std::string& ToolName) const;

    // Auto-generated function.
    friend void PopulateCompilationGraph(CompilationGraph&);

  private:
    // Helper function - find out which language corresponds to the
    // suffix of this file
    const std::string& getLanguage(const llvm::sys::Path& File) const;

    // Return a reference to the tool names list correponding to the
    // given language name. Throws std::runtime_error in case of
    // error.
    const tools_vector_type& getToolsVector(const std::string& LangName) const;
  };

  // Auxiliary class needed to implement GraphTraits support.
  class NodeChildIterator : public bidirectional_iterator<Node, ptrdiff_t> {
    typedef NodeChildIterator ThisType;
    typedef Node::sequence_type::iterator iterator;

    CompilationGraph* OwningGraph;
    iterator KeyIter;
  public:
    typedef Node* pointer;
    typedef Node& reference;

    NodeChildIterator(Node* N, iterator I) :
      OwningGraph(N->OwningGraph), KeyIter(I) {}

    const ThisType& operator=(const ThisType& I) {
      assert(OwningGraph == I.OwningGraph);
      KeyIter = I.KeyIter;
      return *this;
    }

    inline bool operator==(const ThisType& I) const
    { return KeyIter == I.KeyIter; }
    inline bool operator!=(const ThisType& I) const
    { return KeyIter != I.KeyIter; }

    inline pointer operator*() const {
      return &OwningGraph->getNode(*KeyIter);
    }
    inline pointer operator->() const {
      return &OwningGraph->getNode(*KeyIter);
    }

    ThisType& operator++() { ++KeyIter; return *this; } // Preincrement
    ThisType operator++(int) { // Postincrement
      ThisType tmp = *this;
      ++*this;
      return tmp;
    }

    inline ThisType& operator--() { --KeyIter; return *this; }  // Predecrement
    inline ThisType operator--(int) { // Postdecrement
      ThisType tmp = *this;
      --*this;
      return tmp;
    }

  };
}

namespace llvm {
  template <>
  struct GraphTraits<llvmcc::CompilationGraph*> {
    typedef llvmcc::CompilationGraph GraphType;
    typedef llvmcc::Node NodeType;
    typedef llvmcc::NodeChildIterator ChildIteratorType;

    static NodeType* getEntryNode(GraphType* G) {
      return &G->getNode("root");
    }

    static ChildIteratorType child_begin(NodeType* N) {
      return ChildIteratorType(N, N->Children.begin());
    }
    static ChildIteratorType child_end(NodeType* N) {
      return ChildIteratorType(N, N->Children.end());
    }

    typedef GraphType::nodes_iterator nodes_iterator;
    static nodes_iterator nodes_begin(GraphType *G) {
      return G->nodes_begin();
    }
    static nodes_iterator nodes_end(GraphType *G) {
      return G->nodes_end();
    }
  };

}

#endif // LLVM_TOOLS_LLVMC2_COMPILATION_GRAPH_H