Subgraph

Temporary buffer used to add nodes to a Graph.

Most operations on a graph involve adding multiple nodes at once. This type does precisely that, while verifying IR rules, expanding graph memory as needed and wiring up in-neighbors correctly. Last but not least: it will also perform some peephole optimizations (e.g. arithmetic simplification, constant folding and weak strength reduction) automatically.

Constructors

this
this(size_t n)

Initializes a new subgraph with a certain number of preallocated nodes.

Destructor

~this
~this()

Subgraph resources are automatically freed on scope exit (also, it is not a copyable type).

Postblit

A postblit is present on this object, but not explicitly documented in the source.

Members

Aliases

PostHook
alias PostHook = void delegate(const(Node)*, const(Node)*) @(nogc) nothrow

Post-hook callback delegate.

Functions

commit
err_t commit(Graph graph, PostHook postHook)

Commits this subgraph into a parent graph.

insert
AllNodes[kind]* insert(InitParams!(AllNodes[kind]) args)
JoinNode* insert(uint argc)
InstantiationNode* insert()
ConditionalNode* insert()
MultiplexerNode* insert()

Allocates and initializes a new node.

link
err_t link(NodeType* node, InEdge* slot)
err_t link(NodeType* node, InEdge slot)
err_t link(NodeType* node, size_t index, InEdge* slot)
err_t link(NodeType* node, size_t index, InEdge slot)

Links two edge slots within this subgraph.

reserve
err_t reserve(size_t n)

Ensures a certain number of preallocated nodes.

Examples

1 import gyre.mnemonics;
2 
3 Graph graph;
4 graph.initialize(MacroNode.ID(42));
5 scope(exit) graph.dispose();
6 
7 assert(graph.exported == 0);
8 assert(graph.length == 0);
9 
10 // imagine we're compiling something like
11 //    foo(ret, x) {
12 //        a = x + 1
13 //        b = 1 + x
14 //        y = a / b
15 //        ret(y)
16 //    }
17 with (Subgraph.init) {
18     reserve(6);
19 
20     auto foo = insert!func(2);
21     auto jmp = insert!jump(1);
22     auto y = insert!divu;
23     auto a = insert!addnos;
24     auto b = insert!addnos;
25     auto c1 = insert!const_(1);
26 
27     auto params = foo.channels[0];
28     auto ret = &params[0];
29     auto x = &params[1];
30 
31     link!"control"(foo, jmp.control);
32 
33     link!"continuation"(jmp, ret);
34     link!"arguments"(jmp, 0, y.quotient);
35 
36     link!"dividend"(y, a.result);
37     link!"divisor"(y, b.result);
38 
39     link!"lhs"(a, x);
40     link!"rhs"(a, c1.value);
41 
42     link!"lhs"(b, c1.value);
43     link!"rhs"(b, x);
44 
45     commit(graph, (node, inGraph){
46         if (node is foo.asNode) {
47             auto fooInGraph = JoinNode.ofNode(inGraph);
48             graph.export_(fooInGraph.definition);
49         }
50     });
51 }
52 
53 // since `a` and `b` compute the same value, one was CSE'd away
54 assert(graph.length == 5);
55 assert(graph.exported == 1);