summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chapter01/README.md11
-rw-r--r--chapter02/README.md23
-rw-r--r--chapter03/README.md6
-rw-r--r--chapter04/README.md69
-rw-r--r--chapter04/docs/build-graphs.sh2
-rw-r--r--chapter04/docs/lattice.gv63
-rw-r--r--chapter04/docs/lattice.svg195
-rw-r--r--chapter05/README.md4
-rw-r--r--chapter06/README.md31
-rw-r--r--chapter06/docs/build-graphs.sh2
-rw-r--r--chapter06/docs/lattice.gv64
-rw-r--r--chapter06/docs/lattice.svg206
-rw-r--r--chapter10/README.md7
-rw-r--r--chapter10/docs/lattice.gv71
-rw-r--r--chapter10/docs/lattice.svg486
15 files changed, 913 insertions, 327 deletions
diff --git a/chapter01/README.md b/chapter01/README.md
index 62f142e6..fef83683 100644
--- a/chapter01/README.md
+++ b/chapter01/README.md
@@ -25,11 +25,8 @@ If necessary the reader can consult a standard compiler text book.
## Architecture
-We design our parser and compiler to illustrate some key aspects of the Sea of Nodes
-Intermediate Representation:
-
-* We construct the intermediate Sea of Nodes representation directly as we parse the language. There is no Abstract Syntax Tree representation.
-* The compiler will perform a few basic local optimizations as we build the IR; this is a key benefit of the Sea of Nodes IR. This aspect is more fully explored from [Chapter 2](../chapter02/README.md) onwards.
+We construct the intermediate Sea of Nodes (SoN) representation directly as we parse the language. There is no Abstract Syntax Tree representation. The reason for this is to demonstrate a key benefit of the SoN IR:
+a number of pessimistic peephole optimizations can be performed while parsing a language. This aspect is more fully explored from [Chapter 2](../chapter02/README.md) onwards.
## Data Structures
@@ -121,7 +118,7 @@ at very little cost (nearly always small constant time) because all dependencies
Each node is assigned a unique dense integer Node ID when created. This ID is
useful for debugging, efficiently computing equality and e.g. as an index into
a bit vector, which in turn is used to efficiently visit a (possibly cyclic)
-graph. We discuss Node equality in Chapter 9 Global Value Numbering.
+graph. We discuss Node equality in [Chapter 9](../chapter09/README.md).
### Start Node
@@ -148,7 +145,7 @@ The Return node has two inputs. The first input is a control node and the
second is the data node that supplies the return value.
In this presentation, Return functions as a Stop node, since multiple `return` statements are not possible.
-The Stop node will be introduced in Chapter 5 when we implement `if` statements.
+The Stop node will be introduced in [Chapter 5](../chapter05/README.md) when we implement `if` statements.
The Return's output is the value from the data node.
diff --git a/chapter02/README.md b/chapter02/README.md
index 585f6ffc..b5cb5dce 100644
--- a/chapter02/README.md
+++ b/chapter02/README.md
@@ -62,14 +62,14 @@ It is useful for the compiler to know at various points of the program whether
a node's value is a constant. The compiler can use this knowledge to perform various
optimizations such as:
-* Evaluate expressions at compile time and replace an expression with a constant
+* Evaluate expressions at compile time and replace an expression with a constant.
* The compiler may be able to identify regions of code that are dead and no
longer needed, such as when a conditional branch always take one of the
- branches
-* Pointers may be known to be not-null, and a null check can be skipped.
-* Array indices may be known to be in-range, and a range check can be skipped
+ branches ([Chapter 6](../chapter06/README.md)).
+* Pointers may be known to be not-null, and a null check can be skipped ([Chapter 10](../chapter10/README.md)).
+* Array indices may be known to be in-range, and a range check can be skipped.
* Many additional optimizations are possible when the compiler learns more
- about the possible set of Node values
+ about the possible set of Node values.
In order to achieve above, we annotate Nodes with Types.
@@ -95,20 +95,17 @@ structure:
Our lattice elements can be one of three types:
-* the highest element is "top", denoted by T.
-* The lowest is bottom, denoted by ⊥,
-* All elements in the middle are constants.
+* The highest element is "top", denoted by T; assigning T means that the Node's value may or may not be a compile time constant.
+* All elements in the middle are constants.
+* The lowest is "bottom", denoted by ⊥; assigning ⊥ means that we know that the Node's value is **not** a compile time constant.
-Assigning ⊥ means that the Node's value is known to be not a compile time
-constant, whereas assigning T means that the Node's value may be some (as yet)
-undetermined constant. The transition of the Node's type can occur from T to
-some constant to ⊥.
+An invariant of peephole optimizations is that the type of a Node always moves down the lattice.
In later chapters we will explore extending this lattice, as it frequently
forms the heart of core optimizations we want our compiler to do.
There are other important properties of the Lattice that we discuss in [Chapter
-4](../chapter04/README.md), such as the "meet" operator and its rules.
+4](../chapter04/README.md) and [Chapter 10](../chapter10/README.md), such as the "meet" and "join" operators and their rules.
## Nodes Pre Peephole Optimization
diff --git a/chapter03/README.md b/chapter03/README.md
index 07d8fe3e..9b4898ff 100644
--- a/chapter03/README.md
+++ b/chapter03/README.md
@@ -32,9 +32,9 @@ To recap, our list of Nodes are:
In this chapter we introduce:
-| Node Name | Type | Description | Inputs | Value |
-|-----------|------|--------------------------------|---------------------------------|-------|
-| Scope | ? | Represents scopes in the graph | All nodes that define variables | None |
+| Node Name | Type | Description | Inputs | Value |
+|-----------|--------------|--------------------------------|---------------------------------|-------|
+| Scope | Symbol Table | Represents scopes in the graph | All nodes that define variables | None |
## Symbol Tables
diff --git a/chapter04/README.md b/chapter04/README.md
index f938f468..4ae4d432 100644
--- a/chapter04/README.md
+++ b/chapter04/README.md
@@ -19,22 +19,22 @@ Following are revised or new nodes
|-----------|----------------|------------------------------------------------|-----------------------|----------------------------------------------------------------------------|
| MultiNode | Abstract class | A node that has a tuple result | | A tuple |
| Start | Control | Start of function, now a MultiNode | | A tuple with a ctrl token and an `arg` data node |
-| Proj | ? | Projection nodes extract values from MultiNode | A MultiNode and index | Result is the extracted value from the input MultiNode at offset index |
+| Proj | Data | Projection nodes extract values from MultiNode | A MultiNode and index | Result is the extracted value from the input MultiNode at offset index |
| Bool | Data | Represents results of a comparison operator | Two data nodes | Result is a comparison, represented as integer value where 1=true, 0=false |
| Not | Data | Logical not | One data node | Result converts 0 to 1 and vice versa |
Below is our list of Nodes from [Chapter 3](../chapter03/README.md):
-| Node Name | Type | Description | Inputs | Value |
-|-----------|---------|------------------------------------|------------------------------------------------------------------|------------------------------|
-| Return | Control | End of function | Predecessor control node, Data node value | Return value of the function |
-| Constant | Data | Constants such as integer literals | None, however Start node is set as input to enable graph walking | Value of the constant |
-| Add | Data | Add two values | Two data nodes, values are added, order not important | Result of the add operation |
-| Sub | Data | Subtract a value from another | Two data nodes, values are subtracted, order matters | Result of the subtract |
-| Mul | Data | Multiply two values | Two data nodes, values are multiplied, order not important | Result of the multiply |
-| Div | Data | Divide a value by another | Two data nodes, values are divided, order matters | Result of the division |
-| Minus | Data | Negate a value | One data node, value is negated | Result of the unary minus |
-| Scope | ? | Represents scopes in the graph | All nodes that define variables | None |
+| Node Name | Type | Description | Inputs | Value |
+|-----------|--------------|------------------------------------|------------------------------------------------------------------|------------------------------|
+| Return | Control | End of function | Predecessor control node, Data node value | Return value of the function |
+| Constant | Data | Constants such as integer literals | None, however Start node is set as input to enable graph walking | Value of the constant |
+| Add | Data | Add two values | Two data nodes, values are added, order not important | Result of the add operation |
+| Sub | Data | Subtract a value from another | Two data nodes, values are subtracted, order matters | Result of the subtract |
+| Mul | Data | Multiply two values | Two data nodes, values are multiplied, order not important | Result of the multiply |
+| Div | Data | Divide a value by another | Two data nodes, values are divided, order matters | Result of the division |
+| Minus | Data | Negate a value | One data node, value is negated | Result of the unary minus |
+| Scope | Symbol Table | Represents scopes in the graph | All nodes that define variables | None |
## Projection Nodes
@@ -51,13 +51,13 @@ Start node.
## Changes to Type System
-In [Chapter 2](../chapter02/README.md) we introduced the Type System. Here is a summary of key points:
+In [Chapter 2](../chapter02/README.md) we introduced the Type System.
We annotate Nodes with Types.
The Type annotation serves two purposes:
-* it defines the set of operations allowed on the Node, and
+* It defines the set of operations allowed on the Node, and
* it defines the set of values the Node takes on.
The type itself is identified by the Java class sub-typing relationship; all
@@ -76,40 +76,37 @@ Type
We mentioned in [Chapter 2](../chapter02/README.md) that the set of values associated with a Type at a specific Node
can be conveniently represented as a "lattice".
-Our lattice elements can be one of three types:
+Our enhanced Lattice looks like this.
-* the highest element is "top", denoted by T.
-* The lowest is bottom, denoted by ⊥,
-* All elements in the middle are constants.
+![Lattice](./docs/lattice.svg)
-Assigning ⊥ means that the Node's value is known to be not a compile time
-constant, whereas assigning T means that the Node's value may be some (as yet)
-undetermined constant. The transition of the Node's type can occur from T to
-some constant to ⊥.
In this chapter we introduce the possibility of a program input variable named
-`arg`; this variable is usually unknown so ⊥ .
+`arg`; all we know about this variable is that it is some integer value, but we do not know whether it is a constant or not.
To support the requirements for non-constant integer values, we enhance `TypeInteger` to
-allow it to represent `Top` and `Bot` integer types in addition to the earlier constant value.
+allow it to represent `IntTop` and `IntBot` integer types in addition to the earlier constant value.
-Now that integer values may be constants or non-constants, we need to introduce the meet operator
-in our lattice. The meet operator describes rules that define the resulting type when we combine
+Now that integer values may be constants or non-constants, we need to introduce the "meet" operator
+in our lattice. The `meet` operator describes rules that define the resulting type when we combine
integer values.
-| | ⊥ | Con1 | Con2 | T |
-|------|---|------|------|------|
-| ⊥ | ⊥ | ⊥ | ⊥ | ⊥ |
-| Con1 | ⊥ | Con1 | ⊥ | Con1 |
-| T | ⊥ | Con1 | Con2 | T |
+| | IntBot | Con1 | Con2 | IntTop |
+|--------|--------|--------|--------|--------|
+| IntBot | IntBot | IntBot | IntBot | IntBot |
+| Con1 | IntBot | Con1 | IntBot | Con1 |
+| IntTop | IntBot | Con1 | Con2 | IntTop |
+In the table above `Con1` and `Con2` represent two distinct integer values, and serve to explain the rules below.
+
+* The `meet` of `IntTop` with any integer constant is that constant.
+* The `meet` of `IntBot` with any integer value is `IntBot`.
+* The `meet` of any integer with itself is that integer.
+* The `meet` of two unrelated integer constants is `IntBot`.
+
+Currently, all our integer valued nodes are either a constant or a `IntBot` integer type.
+When we start optimizing loops, we will start seeing `IntTop` values.
-The `meet` of `Top` with anything is that thing.
-The `meet` of `Bot` with anything is `Bot`.
-The `meet` of anything with itself is that thing.
-The `meet` of two unrelated constants is `Bot`.
-Currently, all our integer valued nodes are either a constant or a Bottom integer type.
-When we start optimizing loops, we will start seeing Top values.
## `$ctrl` name binding
diff --git a/chapter04/docs/build-graphs.sh b/chapter04/docs/build-graphs.sh
new file mode 100644
index 00000000..d8038602
--- /dev/null
+++ b/chapter04/docs/build-graphs.sh
@@ -0,0 +1,2 @@
+dot -Tsvg lattice.gv > lattice.svg
+
diff --git a/chapter04/docs/lattice.gv b/chapter04/docs/lattice.gv
new file mode 100644
index 00000000..2644448e
--- /dev/null
+++ b/chapter04/docs/lattice.gv
@@ -0,0 +1,63 @@
+digraph Lattice {
+ // Define nodes
+ splines=false;
+ node [shape=circle, style=filled, fillcolor=lightblue];
+ nodesep=0.6;
+
+ TOP [label="⊤"];
+ BOT [label="⊥"];
+
+ CTRL [label="Ctrl"];
+
+ INT_TOP [label="IntTop"];
+ INT_BOT [label="IntBot"];
+
+ INT_MIN [label="-n"];
+ INT_MINDOTS [label="..." shape=none style=none];
+ INT_MINUS [label="-1"];
+ INT_ZERO [label="0"];
+ INT_PLUS [label="1"];
+ INT_MAXDOTS [label="..." shape=none style=none];
+ INT_MAX [label="+n"];
+
+ TUPLE [label="TUPLE"];
+
+ // Define edges
+ edge [arrowhead=none];
+
+ TOP -> INT_TOP;
+ INT_TOP -> INT_MIN;
+ INT_TOP -> INT_MINDOTS;
+ INT_TOP -> INT_MINUS;
+ INT_TOP -> INT_ZERO;
+ INT_TOP -> INT_PLUS;
+ INT_TOP -> INT_MAXDOTS;
+ INT_TOP -> INT_MAX;
+ INT_MIN -> INT_BOT;
+ INT_MINDOTS -> INT_BOT;
+ INT_MINUS -> INT_BOT;
+ INT_ZERO -> INT_BOT;
+ INT_PLUS -> INT_BOT;
+ INT_MAXDOTS -> INT_BOT;
+ INT_MAX -> INT_BOT;
+ INT_BOT -> BOT;
+
+ INT_MIN -> INT_MINDOTS -> INT_MINUS -> INT_ZERO -> INT_PLUS -> INT_MAXDOTS -> INT_MAX [style=invis];
+
+ TOP -> TUPLE;
+ TUPLE -> BOT;
+
+ TOP -> CTRL;
+ CTRL -> BOT;
+
+
+ // Additional customization
+ {rank=same; TOP}
+ {rank=same; INT_TOP}
+ {rank=same; CTRL; INT_MIN; INT_MINDOTS;
+ INT_MINUS; INT_ZERO;
+ INT_PLUS; INT_MAXDOTS;
+ INT_MAX; TUPLE}
+ {rank=same; INT_BOT}
+ {rank=same; BOT;}
+} \ No newline at end of file
diff --git a/chapter04/docs/lattice.svg b/chapter04/docs/lattice.svg
new file mode 100644
index 00000000..0d403c20
--- /dev/null
+++ b/chapter04/docs/lattice.svg
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.43.0 (0)
+ -->
+<!-- Title: Lattice Pages: 1 -->
+<svg width="802pt" height="478pt"
+ viewBox="0.00 0.00 802.14 478.27" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 474.27)">
+<title>Lattice</title>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-474.27 798.14,-474.27 798.14,4 -4,4"/>
+<!-- TOP -->
+<g id="node1" class="node">
+<title>TOP</title>
+<ellipse fill="lightblue" stroke="black" cx="377.6" cy="-450.77" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="377.6" y="-447.07" font-family="Times,serif" font-size="14.00">⊤</text>
+</g>
+<!-- CTRL -->
+<g id="node3" class="node">
+<title>CTRL</title>
+<ellipse fill="lightblue" stroke="black" cx="28.6" cy="-235.14" rx="28.7" ry="28.7"/>
+<text text-anchor="middle" x="28.6" y="-231.44" font-family="Times,serif" font-size="14.00">Ctrl</text>
+</g>
+<!-- TOP&#45;&gt;CTRL -->
+<g id="edge25" class="edge">
+<title>TOP&#45;&gt;CTRL</title>
+<path fill="none" stroke="black" d="M360.76,-440.37C304.12,-405.37 120.24,-291.76 53.28,-250.38"/>
+</g>
+<!-- INT_TOP -->
+<g id="node4" class="node">
+<title>INT_TOP</title>
+<ellipse fill="lightblue" stroke="black" cx="377.6" cy="-354.98" rx="40.09" ry="40.09"/>
+<text text-anchor="middle" x="377.6" y="-351.28" font-family="Times,serif" font-size="14.00">IntTop</text>
+</g>
+<!-- TOP&#45;&gt;INT_TOP -->
+<g id="edge1" class="edge">
+<title>TOP&#45;&gt;INT_TOP</title>
+<path fill="none" stroke="black" d="M377.6,-431.24C377.6,-420.99 377.6,-407.84 377.6,-395.42"/>
+</g>
+<!-- TUPLE -->
+<g id="node13" class="node">
+<title>TUPLE</title>
+<ellipse fill="lightblue" stroke="black" cx="750.6" cy="-235.14" rx="43.59" ry="43.59"/>
+<text text-anchor="middle" x="750.6" y="-231.44" font-family="Times,serif" font-size="14.00">TUPLE</text>
+</g>
+<!-- TOP&#45;&gt;TUPLE -->
+<g id="edge23" class="edge">
+<title>TOP&#45;&gt;TUPLE</title>
+<path fill="none" stroke="black" d="M394.59,-440.95C451.03,-408.32 633.13,-303.05 712.75,-257.02"/>
+</g>
+<!-- BOT -->
+<g id="node2" class="node">
+<title>BOT</title>
+<ellipse fill="lightblue" stroke="black" cx="377.6" cy="-19.5" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="377.6" y="-15.8" font-family="Times,serif" font-size="14.00">⊥</text>
+</g>
+<!-- CTRL&#45;&gt;BOT -->
+<g id="edge26" class="edge">
+<title>CTRL&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M53.14,-219.97C120.01,-178.65 304.22,-64.84 360.83,-29.86"/>
+</g>
+<!-- INT_MIN -->
+<g id="node6" class="node">
+<title>INT_MIN</title>
+<ellipse fill="lightblue" stroke="black" cx="119.6" cy="-235.14" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="119.6" y="-231.44" font-family="Times,serif" font-size="14.00">&#45;n</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MIN -->
+<g id="edge2" class="edge">
+<title>INT_TOP&#45;&gt;INT_MIN</title>
+<path fill="none" stroke="black" d="M341.18,-337.34C284.92,-311.65 179.02,-263.28 137.21,-244.18"/>
+</g>
+<!-- INT_MINDOTS -->
+<g id="node7" class="node">
+<title>INT_MINDOTS</title>
+<text text-anchor="middle" x="208.6" y="-231.44" font-family="Times,serif" font-size="14.00">...</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MINDOTS -->
+<g id="edge3" class="edge">
+<title>INT_TOP&#45;&gt;INT_MINDOTS</title>
+<path fill="none" stroke="black" d="M345.01,-331.26C312.3,-308.45 262.65,-273.83 233.14,-253.25"/>
+</g>
+<!-- INT_MINUS -->
+<g id="node8" class="node">
+<title>INT_MINUS</title>
+<ellipse fill="lightblue" stroke="black" cx="297.6" cy="-235.14" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="297.6" y="-231.44" font-family="Times,serif" font-size="14.00">&#45;1</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MINUS -->
+<g id="edge4" class="edge">
+<title>INT_TOP&#45;&gt;INT_MINUS</title>
+<path fill="none" stroke="black" d="M355.31,-321.15C339.96,-298.54 320.25,-269.51 308.29,-251.89"/>
+</g>
+<!-- INT_ZERO -->
+<g id="node9" class="node">
+<title>INT_ZERO</title>
+<ellipse fill="lightblue" stroke="black" cx="377.6" cy="-235.14" rx="18" ry="18"/>
+<text text-anchor="middle" x="377.6" y="-231.44" font-family="Times,serif" font-size="14.00">0</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_ZERO -->
+<g id="edge5" class="edge">
+<title>INT_TOP&#45;&gt;INT_ZERO</title>
+<path fill="none" stroke="black" d="M377.6,-314.41C377.6,-293.68 377.6,-269.36 377.6,-253.39"/>
+</g>
+<!-- INT_PLUS -->
+<g id="node10" class="node">
+<title>INT_PLUS</title>
+<ellipse fill="lightblue" stroke="black" cx="456.6" cy="-235.14" rx="18" ry="18"/>
+<text text-anchor="middle" x="456.6" y="-231.44" font-family="Times,serif" font-size="14.00">1</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_PLUS -->
+<g id="edge6" class="edge">
+<title>INT_TOP&#45;&gt;INT_PLUS</title>
+<path fill="none" stroke="black" d="M399.6,-321.15C415.13,-298 435.17,-268.1 446.88,-250.63"/>
+</g>
+<!-- INT_MAXDOTS -->
+<g id="node11" class="node">
+<title>INT_MAXDOTS</title>
+<text text-anchor="middle" x="544.6" y="-231.44" font-family="Times,serif" font-size="14.00">...</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MAXDOTS -->
+<g id="edge7" class="edge">
+<title>INT_TOP&#45;&gt;INT_MAXDOTS</title>
+<path fill="none" stroke="black" d="M410.19,-330.98C442.56,-308.14 491.43,-273.65 520.47,-253.16"/>
+</g>
+<!-- INT_MAX -->
+<g id="node12" class="node">
+<title>INT_MAX</title>
+<ellipse fill="lightblue" stroke="black" cx="639.6" cy="-235.14" rx="24.9" ry="24.9"/>
+<text text-anchor="middle" x="639.6" y="-231.44" font-family="Times,serif" font-size="14.00">+n</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MAX -->
+<g id="edge8" class="edge">
+<title>INT_TOP&#45;&gt;INT_MAX</title>
+<path fill="none" stroke="black" d="M414.03,-337.59C469.15,-312.8 572.09,-266.5 617.32,-246.16"/>
+</g>
+<!-- INT_BOT -->
+<g id="node5" class="node">
+<title>INT_BOT</title>
+<ellipse fill="lightblue" stroke="black" cx="377.6" cy="-115.29" rx="40.09" ry="40.09"/>
+<text text-anchor="middle" x="377.6" y="-111.59" font-family="Times,serif" font-size="14.00">IntBot</text>
+</g>
+<!-- INT_BOT&#45;&gt;BOT -->
+<g id="edge16" class="edge">
+<title>INT_BOT&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M377.6,-74.79C377.6,-62.37 377.6,-49.25 377.6,-39.01"/>
+</g>
+<!-- INT_MIN&#45;&gt;INT_BOT -->
+<g id="edge9" class="edge">
+<title>INT_MIN&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M137.33,-226.04C179.23,-206.9 285.02,-158.58 341.21,-132.91"/>
+</g>
+<!-- INT_MIN&#45;&gt;INT_MINDOTS -->
+<!-- INT_MINDOTS&#45;&gt;INT_BOT -->
+<g id="edge10" class="edge">
+<title>INT_MINDOTS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M233.17,-217C262.65,-196.45 312.17,-161.91 344.87,-139.11"/>
+</g>
+<!-- INT_MINDOTS&#45;&gt;INT_MINUS -->
+<!-- INT_MINUS&#45;&gt;INT_BOT -->
+<g id="edge11" class="edge">
+<title>INT_MINUS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M308.39,-218.24C320.33,-200.65 339.91,-171.81 355.2,-149.29"/>
+</g>
+<!-- INT_MINUS&#45;&gt;INT_ZERO -->
+<!-- INT_ZERO&#45;&gt;INT_BOT -->
+<g id="edge12" class="edge">
+<title>INT_ZERO&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M377.6,-217C377.6,-201.04 377.6,-176.66 377.6,-155.88"/>
+</g>
+<!-- INT_ZERO&#45;&gt;INT_PLUS -->
+<!-- INT_PLUS&#45;&gt;INT_BOT -->
+<g id="edge13" class="edge">
+<title>INT_PLUS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M446.91,-219.69C435.21,-202.23 415.16,-172.33 399.63,-149.16"/>
+</g>
+<!-- INT_PLUS&#45;&gt;INT_MAXDOTS -->
+<!-- INT_MAXDOTS&#45;&gt;INT_BOT -->
+<g id="edge14" class="edge">
+<title>INT_MAXDOTS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M520.31,-217C491.28,-196.51 442.55,-162.13 410.24,-139.33"/>
+</g>
+<!-- INT_MAXDOTS&#45;&gt;INT_MAX -->
+<!-- INT_MAX&#45;&gt;INT_BOT -->
+<g id="edge15" class="edge">
+<title>INT_MAX&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M617.26,-224.09C572.09,-203.77 469.52,-157.64 414.35,-132.82"/>
+</g>
+<!-- TUPLE&#45;&gt;BOT -->
+<g id="edge24" class="edge">
+<title>TUPLE&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M712.78,-213.27C633.14,-167.23 450.85,-61.85 394.51,-29.27"/>
+</g>
+</g>
+</svg>
diff --git a/chapter05/README.md b/chapter05/README.md
index dbe3c8e2..f06e5e15 100644
--- a/chapter05/README.md
+++ b/chapter05/README.md
@@ -27,7 +27,7 @@ Here is a recap of the nodes introduced in previous chapters:
|-----------|----------------|---------|------------------------------------------------|-------------------------------------------------------------------------------|----------------------------------------------------------------------------|
| Multi | Abstract class | 4 | A node that has a tuple result | | A tuple |
| Start | Control | 1 | Start of function, now a MultiNode | | A tuple with a ctrl token and an `arg` data node |
-| Proj | ? | 4 | Projection nodes extract values from MultiNode | A MultiNode and index | Result is the extracted value from the input MultiNode at offset index |
+| Proj | Data | 4 | Projection nodes extract values from MultiNode | A MultiNode and index | Result is the extracted value from the input MultiNode at offset index |
| Bool | Data | 4 | Represents results of a comparison operator | Two data nodes | Result is a comparison, represented as integer value where 1=true, 0=false |
| Not | Data | 4 | Logical not | One data node | Result converts 0 to 1 and vice versa |
| Return | Control | 1 | End of function | Predecessor control node and a data node for the return value of the function | Return value of the function |
@@ -37,7 +37,7 @@ Here is a recap of the nodes introduced in previous chapters:
| Mul | Data | 2 | Multiply two values | Two data nodes without restrictions on the order | Result of the multiplication |
| Div | Data | 2 | Divide a value by another | Two data nodes, the first one is divided by the second one | Result of the division |
| Minus | Data | 2 | Negate a value | One data node which value is negated | Result of the negation |
-| Scope | ? | 3 | Represents scopes in the graph | Nodes that represent the current value of variables | None |
+| Scope | Symbol Table | 3 | Represents scopes in the graph | Nodes that represent the current value of variables | None |
## `If` Nodes
diff --git a/chapter06/README.md b/chapter06/README.md
index d3fe6ed9..6f7f3baa 100644
--- a/chapter06/README.md
+++ b/chapter06/README.md
@@ -4,11 +4,11 @@ In this chapter we do not add new language features. Our goal is to add peephole
## Type System Revision
-We now need to extend the type system to introduce another lattice structure, in addition to the Integer lattice.
-As before we denote "top" by T and "bottom" by ⊥.
+We now need to extend the type system to introduce another lattice structure, in addition to the Integer sub-lattice.
+As before we denote "Top" by T and "Bottom" by ⊥.
-* "ctrl" represents a live control, whereas "~ctrl" represents a dead control.
-* "INT" refers to the integer type.
+* "Ctrl" represents a live control, whereas "~Ctrl" represents a dead control.
+* "INT" refers to an integer value, note that integer values have their own sub-lattice.
| | ⊥ | Ctrl | ~Ctrl | T | INT |
|-------|---|------|-------|-------|-----|
@@ -17,11 +17,16 @@ As before we denote "top" by T and "bottom" by ⊥.
| ~Ctrl | ⊥ | Ctrl | ~Ctrl | ~Ctrl | ⊥ |
| ⊥ | ⊥ | ⊥ | ⊥ | ⊥ | ⊥ |
-* "top" meets any type is that type,
-* "bottom" meets any type is "bottom",
-* "top", "bottom", "ctrl", "~ctrl" are classed as simple types,
-* "ctrl" meets "~ctrl" is "ctrl"
-* Unless covered above, a simple type meets non-simple results in "bottom"
+* "Top" meets any type is that type,
+* "Bottom" meets any type is "Bottom",
+* "Top", "Bottom", "Ctrl", "~Ctrl" are classed as simple types,
+* "Ctrl" meets "~Ctrl" is "Ctrl"
+* Unless covered above, a simple type meets non-simple results in "Bottom"
+
+The entire revised Lattice is shown below:
+
+![Lattice](./docs/lattice.svg)
+
## Peephole of `if`
@@ -33,7 +38,7 @@ As before we denote "top" by T and "bottom" by ⊥.
* When we peephole an `If` node we test if the predicate is a constant. If so,
then one branch or the other dead, depending on if the constant is `0` or not.
* When we add the `Proj` nodes, in this scenario, we already know one of the projections is dead. The peephole of the
- relevant `Proj` node replaces the `Proj` with a `Constant` of type "~ctrl" indicating dead control.
+ relevant `Proj` node replaces the `Proj` with a `Constant` of type "~Ctrl" indicating dead control.
* At this point our dead code elimination would kill the `If` node since it has no uses
- but we cannot do that because we need to continue the parse. The
important observation is that *we __can__ kill the `If` node after __both__
@@ -41,11 +46,11 @@ As before we denote "top" by T and "bottom" by ⊥.
only see the `Proj` nodes.
* To ensure this, we add a dummy user to `If` before creating the first `Proj` and remove it immediately after, allowing the
second `Proj` to trigger a dead code elimination of the `If`.
-* The live `Proj` gets replaced by the parent of `If`, whereas the dead `Proj` gets replaced by "~ctrl".
+* The live `Proj` gets replaced by the parent of `If`, whereas the dead `Proj` gets replaced by "~Ctrl".
* The parsing then continues as normal.
* The other changes are when we reach the merge point with a dead control.
* Again keeping with our strategy we merge as normal, including creating `Phi` nodes.
-* The `Region` may have have one of its inputs as "~ctrl". This will be seen
+* The `Region` may have have one of its inputs as "~Ctrl". This will be seen
by the `Phi` which then optimizes itself. If the `Phi` has just one live
input, the `Phi` peephole replaces itself with the remaining input.
* Finally, at the end, when the `Region` node is peepholed, we see that it has only one live input and no Phi uses
@@ -60,7 +65,7 @@ deleted. Conversely, we cannot collapse a Region until it has no dependent
`Phi`s.
When processing `If` we do not remove control inputs to a `Region`, instead the
-dead control input is simply set to `Constant(~ctrl)`. The peephole logic in
+dead control input is simply set to `Constant(~Ctrl)`. The peephole logic in
a `Phi` notices this and replaces itself with the live input.
## Discussion
diff --git a/chapter06/docs/build-graphs.sh b/chapter06/docs/build-graphs.sh
index 5238dbfc..44d2de3a 100644
--- a/chapter06/docs/build-graphs.sh
+++ b/chapter06/docs/build-graphs.sh
@@ -9,3 +9,5 @@ dot -Tsvg 06-graph3-false.gv > 06-graph3-false.svg
dot -Tsvg 06-graph4-nonconst.gv > 06-graph4-nonconst.svg
dot -Tsvg 06-graph4-true.gv > 06-graph4-true.svg
dot -Tsvg 06-graph4-arg2.gv > 06-graph4-arg2.svg
+dot -Tsvg lattice.gv > lattice.svg
+
diff --git a/chapter06/docs/lattice.gv b/chapter06/docs/lattice.gv
new file mode 100644
index 00000000..2cf27452
--- /dev/null
+++ b/chapter06/docs/lattice.gv
@@ -0,0 +1,64 @@
+digraph Lattice {
+ // Define nodes
+ splines=false;
+ node [shape=circle, style=filled, fillcolor=lightblue];
+ nodesep=0.6;
+
+ TOP [label="⊤"];
+ BOT [label="⊥"];
+
+ XCTRL [label="~Ctrl"];
+ CTRL [label="Ctrl"];
+
+ INT_TOP [label="IntTop"];
+ INT_BOT [label="IntBot"];
+
+ INT_MIN [label="-n"];
+ INT_MINDOTS [label="..." shape=none style=none];
+ INT_MINUS [label="-1"];
+ INT_ZERO [label="0"];
+ INT_PLUS [label="1"];
+ INT_MAXDOTS [label="..." shape=none style=none];
+ INT_MAX [label="+n"];
+
+ TUPLE [label="TUPLE"];
+
+ // Define edges
+ edge [arrowhead=none];
+
+ TOP -> INT_TOP;
+ INT_TOP -> INT_MIN;
+ INT_TOP -> INT_MINDOTS;
+ INT_TOP -> INT_MINUS;
+ INT_TOP -> INT_ZERO;
+ INT_TOP -> INT_PLUS;
+ INT_TOP -> INT_MAXDOTS;
+ INT_TOP -> INT_MAX;
+ INT_MIN -> INT_BOT;
+ INT_MINDOTS -> INT_BOT;
+ INT_MINUS -> INT_BOT;
+ INT_ZERO -> INT_BOT;
+ INT_PLUS -> INT_BOT;
+ INT_MAXDOTS -> INT_BOT;
+ INT_MAX -> INT_BOT;
+ INT_BOT -> BOT;
+
+ INT_MIN -> INT_MINDOTS -> INT_MINUS -> INT_ZERO -> INT_PLUS -> INT_MAXDOTS -> INT_MAX [style=invis];
+
+ TOP -> TUPLE;
+ TUPLE -> BOT;
+
+ TOP -> XCTRL;
+ XCTRL -> CTRL;
+ CTRL -> BOT;
+
+ // Additional customization
+ {rank=same; TOP}
+ {rank=same; INT_TOP; XCTRL}
+ {rank=same; INT_MIN; INT_MINDOTS;
+ INT_MINUS; INT_ZERO;
+ INT_PLUS; INT_MAXDOTS;
+ INT_MAX; TUPLE}
+ {rank=same; INT_BOT; CTRL}
+ {rank=same; BOT;}
+} \ No newline at end of file
diff --git a/chapter06/docs/lattice.svg b/chapter06/docs/lattice.svg
new file mode 100644
index 00000000..713b54c1
--- /dev/null
+++ b/chapter06/docs/lattice.svg
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.43.0 (0)
+ -->
+<!-- Title: Lattice Pages: 1 -->
+<svg width="702pt" height="478pt"
+ viewBox="0.00 0.00 702.04 478.27" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 474.27)">
+<title>Lattice</title>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-474.27 698.04,-474.27 698.04,4 -4,4"/>
+<!-- TOP -->
+<g id="node1" class="node">
+<title>TOP</title>
+<ellipse fill="lightblue" stroke="black" cx="277.5" cy="-450.77" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="277.5" y="-447.07" font-family="Times,serif" font-size="14.00">⊤</text>
+</g>
+<!-- XCTRL -->
+<g id="node3" class="node">
+<title>XCTRL</title>
+<ellipse fill="lightblue" stroke="black" cx="46.5" cy="-354.98" rx="36.29" ry="36.29"/>
+<text text-anchor="middle" x="46.5" y="-351.28" font-family="Times,serif" font-size="14.00">~Ctrl</text>
+</g>
+<!-- TOP&#45;&gt;XCTRL -->
+<g id="edge25" class="edge">
+<title>TOP&#45;&gt;XCTRL</title>
+<path fill="none" stroke="black" d="M259.76,-442.57C221.3,-426.95 129.74,-389.78 80.01,-369.59"/>
+</g>
+<!-- INT_TOP -->
+<g id="node5" class="node">
+<title>INT_TOP</title>
+<ellipse fill="lightblue" stroke="black" cx="277.5" cy="-354.98" rx="40.09" ry="40.09"/>
+<text text-anchor="middle" x="277.5" y="-351.28" font-family="Times,serif" font-size="14.00">IntTop</text>
+</g>
+<!-- TOP&#45;&gt;INT_TOP -->
+<g id="edge1" class="edge">
+<title>TOP&#45;&gt;INT_TOP</title>
+<path fill="none" stroke="black" d="M277.5,-431.24C277.5,-420.99 277.5,-407.84 277.5,-395.42"/>
+</g>
+<!-- TUPLE -->
+<g id="node14" class="node">
+<title>TUPLE</title>
+<ellipse fill="lightblue" stroke="black" cx="650.5" cy="-235.14" rx="43.59" ry="43.59"/>
+<text text-anchor="middle" x="650.5" y="-231.44" font-family="Times,serif" font-size="14.00">TUPLE</text>
+</g>
+<!-- TOP&#45;&gt;TUPLE -->
+<g id="edge23" class="edge">
+<title>TOP&#45;&gt;TUPLE</title>
+<path fill="none" stroke="black" d="M294.49,-440.95C350.93,-408.32 533.03,-303.05 612.65,-257.02"/>
+</g>
+<!-- BOT -->
+<g id="node2" class="node">
+<title>BOT</title>
+<ellipse fill="lightblue" stroke="black" cx="277.5" cy="-19.5" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="277.5" y="-15.8" font-family="Times,serif" font-size="14.00">⊥</text>
+</g>
+<!-- CTRL -->
+<g id="node4" class="node">
+<title>CTRL</title>
+<ellipse fill="lightblue" stroke="black" cx="50.5" cy="-115.29" rx="28.7" ry="28.7"/>
+<text text-anchor="middle" x="50.5" y="-111.59" font-family="Times,serif" font-size="14.00">Ctrl</text>
+</g>
+<!-- XCTRL&#45;&gt;CTRL -->
+<g id="edge26" class="edge">
+<title>XCTRL&#45;&gt;CTRL</title>
+<path fill="none" stroke="black" d="M47.11,-318.58C47.9,-270.77 49.29,-187.82 50.02,-144.12"/>
+</g>
+<!-- CTRL&#45;&gt;BOT -->
+<g id="edge27" class="edge">
+<title>CTRL&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M76.98,-103.35C123.76,-84.02 219.83,-44.32 259.63,-27.88"/>
+</g>
+<!-- INT_MIN -->
+<g id="node7" class="node">
+<title>INT_MIN</title>
+<ellipse fill="lightblue" stroke="black" cx="19.5" cy="-235.14" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="19.5" y="-231.44" font-family="Times,serif" font-size="14.00">&#45;n</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MIN -->
+<g id="edge2" class="edge">
+<title>INT_TOP&#45;&gt;INT_MIN</title>
+<path fill="none" stroke="black" d="M241.08,-337.34C184.83,-311.65 78.92,-263.28 37.12,-244.18"/>
+</g>
+<!-- INT_MINDOTS -->
+<g id="node8" class="node">
+<title>INT_MINDOTS</title>
+<text text-anchor="middle" x="108.5" y="-231.44" font-family="Times,serif" font-size="14.00">...</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MINDOTS -->
+<g id="edge3" class="edge">
+<title>INT_TOP&#45;&gt;INT_MINDOTS</title>
+<path fill="none" stroke="black" d="M244.91,-331.26C212.21,-308.45 162.56,-273.83 133.04,-253.25"/>
+</g>
+<!-- INT_MINUS -->
+<g id="node9" class="node">
+<title>INT_MINUS</title>
+<ellipse fill="lightblue" stroke="black" cx="197.5" cy="-235.14" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="197.5" y="-231.44" font-family="Times,serif" font-size="14.00">&#45;1</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MINUS -->
+<g id="edge4" class="edge">
+<title>INT_TOP&#45;&gt;INT_MINUS</title>
+<path fill="none" stroke="black" d="M255.21,-321.15C239.86,-298.54 220.15,-269.51 208.19,-251.89"/>
+</g>
+<!-- INT_ZERO -->
+<g id="node10" class="node">
+<title>INT_ZERO</title>
+<ellipse fill="lightblue" stroke="black" cx="277.5" cy="-235.14" rx="18" ry="18"/>
+<text text-anchor="middle" x="277.5" y="-231.44" font-family="Times,serif" font-size="14.00">0</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_ZERO -->
+<g id="edge5" class="edge">
+<title>INT_TOP&#45;&gt;INT_ZERO</title>
+<path fill="none" stroke="black" d="M277.5,-314.41C277.5,-293.68 277.5,-269.36 277.5,-253.39"/>
+</g>
+<!-- INT_PLUS -->
+<g id="node11" class="node">
+<title>INT_PLUS</title>
+<ellipse fill="lightblue" stroke="black" cx="356.5" cy="-235.14" rx="18" ry="18"/>
+<text text-anchor="middle" x="356.5" y="-231.44" font-family="Times,serif" font-size="14.00">1</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_PLUS -->
+<g id="edge6" class="edge">
+<title>INT_TOP&#45;&gt;INT_PLUS</title>
+<path fill="none" stroke="black" d="M299.5,-321.15C315.03,-298 335.07,-268.1 346.78,-250.63"/>
+</g>
+<!-- INT_MAXDOTS -->
+<g id="node12" class="node">
+<title>INT_MAXDOTS</title>
+<text text-anchor="middle" x="444.5" y="-231.44" font-family="Times,serif" font-size="14.00">...</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MAXDOTS -->
+<g id="edge7" class="edge">
+<title>INT_TOP&#45;&gt;INT_MAXDOTS</title>
+<path fill="none" stroke="black" d="M310.09,-330.98C342.46,-308.14 391.33,-273.65 420.37,-253.16"/>
+</g>
+<!-- INT_MAX -->
+<g id="node13" class="node">
+<title>INT_MAX</title>
+<ellipse fill="lightblue" stroke="black" cx="539.5" cy="-235.14" rx="24.9" ry="24.9"/>
+<text text-anchor="middle" x="539.5" y="-231.44" font-family="Times,serif" font-size="14.00">+n</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_MAX -->
+<g id="edge8" class="edge">
+<title>INT_TOP&#45;&gt;INT_MAX</title>
+<path fill="none" stroke="black" d="M313.93,-337.59C369.05,-312.8 471.99,-266.5 517.22,-246.16"/>
+</g>
+<!-- INT_BOT -->
+<g id="node6" class="node">
+<title>INT_BOT</title>
+<ellipse fill="lightblue" stroke="black" cx="277.5" cy="-115.29" rx="40.09" ry="40.09"/>
+<text text-anchor="middle" x="277.5" y="-111.59" font-family="Times,serif" font-size="14.00">IntBot</text>
+</g>
+<!-- INT_BOT&#45;&gt;BOT -->
+<g id="edge16" class="edge">
+<title>INT_BOT&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M277.5,-74.79C277.5,-62.37 277.5,-49.25 277.5,-39.01"/>
+</g>
+<!-- INT_MIN&#45;&gt;INT_BOT -->
+<g id="edge9" class="edge">
+<title>INT_MIN&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M37.23,-226.04C79.13,-206.9 184.92,-158.58 241.11,-132.91"/>
+</g>
+<!-- INT_MIN&#45;&gt;INT_MINDOTS -->
+<!-- INT_MINDOTS&#45;&gt;INT_BOT -->
+<g id="edge10" class="edge">
+<title>INT_MINDOTS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M133.07,-217C162.55,-196.45 212.07,-161.91 244.77,-139.11"/>
+</g>
+<!-- INT_MINDOTS&#45;&gt;INT_MINUS -->
+<!-- INT_MINUS&#45;&gt;INT_BOT -->
+<g id="edge11" class="edge">
+<title>INT_MINUS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M208.29,-218.24C220.23,-200.65 239.81,-171.81 255.1,-149.29"/>
+</g>
+<!-- INT_MINUS&#45;&gt;INT_ZERO -->
+<!-- INT_ZERO&#45;&gt;INT_BOT -->
+<g id="edge12" class="edge">
+<title>INT_ZERO&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M277.5,-217C277.5,-201.04 277.5,-176.66 277.5,-155.88"/>
+</g>
+<!-- INT_ZERO&#45;&gt;INT_PLUS -->
+<!-- INT_PLUS&#45;&gt;INT_BOT -->
+<g id="edge13" class="edge">
+<title>INT_PLUS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M346.81,-219.69C335.11,-202.23 315.06,-172.33 299.53,-149.16"/>
+</g>
+<!-- INT_PLUS&#45;&gt;INT_MAXDOTS -->
+<!-- INT_MAXDOTS&#45;&gt;INT_BOT -->
+<g id="edge14" class="edge">
+<title>INT_MAXDOTS&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M420.22,-217C391.18,-196.51 342.45,-162.13 310.14,-139.33"/>
+</g>
+<!-- INT_MAXDOTS&#45;&gt;INT_MAX -->
+<!-- INT_MAX&#45;&gt;INT_BOT -->
+<g id="edge15" class="edge">
+<title>INT_MAX&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M517.16,-224.09C471.99,-203.77 369.42,-157.64 314.25,-132.82"/>
+</g>
+<!-- TUPLE&#45;&gt;BOT -->
+<g id="edge24" class="edge">
+<title>TUPLE&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M612.68,-213.27C533.04,-167.23 350.75,-61.85 294.41,-29.27"/>
+</g>
+</g>
+</svg>
diff --git a/chapter10/README.md b/chapter10/README.md
index a25ff011..1fb69feb 100644
--- a/chapter10/README.md
+++ b/chapter10/README.md
@@ -126,6 +126,7 @@ Within the Type Lattice, we now have the following type domains:
* Control type - this represents control flow
* Integer type - Integer values
+* Tuple type - when a Node results in more than one value
* Struct type (new) - Represents user defined struct types, a struct type is allowed to have members of Integer type only in this chapter
* `$TOP` represents local Top for struct type; all we know about the type is that it is a struct but, we do not know if it is a specific struct, or all possible structs, etc.
* `$BOT` represents local Bottom for struct type; we definitely know the value can take all possible struct types.
@@ -274,6 +275,12 @@ The graph from above will have the shape:
![Graph1](./docs/example1.svg)
+The graph visual has the following enhancements:
+
+* The memory edges are shown in green and blue.
+* The green edges occur on New nodes and anchor the ptr to a control flow node.
+* The blue edges show the threading of a memory op via the equivalence aliasing.
+
## Additional Peephole Optimizations
The equivalence aliasing makes it possible to optimize following scenarios:
diff --git a/chapter10/docs/lattice.gv b/chapter10/docs/lattice.gv
index 406a62c3..bf7403f7 100644
--- a/chapter10/docs/lattice.gv
+++ b/chapter10/docs/lattice.gv
@@ -7,32 +7,35 @@ digraph Lattice {
TOP [label="⊤"];
BOT [label="⊥"];
- CTRL [label="Ctrl"];
XCTRL [label="~Ctrl"];
+ CTRL [label="Ctrl"];
INT_TOP [label="IntTop"];
INT_BOT [label="IntBot"];
INT_MIN [label="-n"];
INT_MINDOTS [label="..." shape=none style=none];
- INT_MINUS [label="-1"];
INT_ZERO [label="0"];
- INT_PLUS [label="1"];
INT_MAXDOTS [label="..." shape=none style=none];
INT_MAX [label="+n"];
+ TUPLE [label="TUPLE"];
+
STRUCT_TOP [label="$TOP"];
STRUCT_S1 [label="S1"];
- STRUCT_S2 [label="S2"];
+ STRUCT_DOTS [label="..." shape=none style=none];
+ STRUCT_SN [label="Sn"];
STRUCT_BOT [label="$BOT"]
PTR_TOP [label="*$TOP"];
PTR_NULL [label="null"];
PTR_VOIDPTR [label="*void"];
PTR_S1 [label="*S1"];
- PTR_S2 [label="*S2"];
+ PTR_SDOTS [label="..." shape=none style=none];
+ PTR_SN [label="*SN"];
PTR_S1OPT [label="*S1?"];
- PTR_S2OPT [label="*S2?"];
+ PTR_SOPTDOTS [label="..." shape=none style=none];
+ PTR_SNOPT [label="*SN?"];
PTR_BOT [label="*$BOT?"];
MEM_TOP [label="MEM#TOP"];
@@ -45,53 +48,64 @@ digraph Lattice {
// Define edges
edge [arrowhead=none];
- TOP -> CTRL;
- CTRL -> XCTRL;
- XCTRL -> BOT;
+ TOP -> XCTRL;
+ XCTRL -> CTRL;
+ CTRL -> BOT;
TOP -> INT_TOP;
INT_TOP -> INT_MIN;
INT_TOP -> INT_MINDOTS;
- INT_TOP -> INT_MINUS;
INT_TOP -> INT_ZERO;
- INT_TOP -> INT_PLUS;
INT_TOP -> INT_MAXDOTS;
INT_TOP -> INT_MAX;
INT_MIN -> INT_BOT;
INT_MINDOTS -> INT_BOT;
- INT_MINUS -> INT_BOT;
INT_ZERO -> INT_BOT;
- INT_PLUS -> INT_BOT;
INT_MAXDOTS -> INT_BOT;
INT_MAX -> INT_BOT;
INT_BOT -> BOT;
- INT_MIN -> INT_MINDOTS -> INT_MINUS -> INT_ZERO -> INT_PLUS -> INT_MAXDOTS -> INT_MAX [style=invis];
+ INT_MIN -> INT_MINDOTS -> INT_ZERO -> INT_MAXDOTS -> INT_MAX [style=invis];
+
+ TOP -> TUPLE;
+ TUPLE -> BOT;
TOP -> STRUCT_TOP;
STRUCT_TOP -> STRUCT_S1;
- STRUCT_TOP -> STRUCT_S2;
+ STRUCT_TOP -> STRUCT_DOTS;
+ STRUCT_TOP -> STRUCT_SN;
STRUCT_S1 -> STRUCT_BOT;
- STRUCT_S2 -> STRUCT_BOT;
+ STRUCT_DOTS -> STRUCT_BOT;
+ STRUCT_SN -> STRUCT_BOT;
STRUCT_BOT -> BOT;
+ STRUCT_S1 -> STRUCT_DOTS -> STRUCT_SN [style=invis];
+
TOP -> PTR_TOP;
PTR_TOP -> PTR_S1;
- PTR_TOP -> PTR_S2;
+ PTR_TOP -> PTR_SDOTS;
+ PTR_TOP -> PTR_SN;
PTR_TOP -> PTR_NULL;
PTR_TOP -> PTR_VOIDPTR;
PTR_NULL -> PTR_BOT;
PTR_NULL -> PTR_S1OPT;
- PTR_NULL -> PTR_S2OPT;
+ PTR_NULL -> PTR_SOPTDOTS;
+ PTR_NULL -> PTR_SNOPT;
PTR_S1 -> PTR_S1OPT;
PTR_S1 -> PTR_VOIDPTR;
- PTR_S2 -> PTR_S2OPT;
- PTR_S2 -> PTR_VOIDPTR;
+ PTR_SDOTS -> PTR_SOPTDOTS;
+ PTR_SDOTS -> PTR_VOIDPTR;
+ PTR_SN -> PTR_SNOPT;
+ PTR_SN -> PTR_VOIDPTR;
PTR_VOIDPTR -> PTR_BOT;
PTR_S1OPT -> PTR_BOT;
- PTR_S2OPT -> PTR_BOT;
+ PTR_SOPTDOTS -> PTR_BOT;
+ PTR_SNOPT -> PTR_BOT;
PTR_BOT -> BOT;
+ PTR_S1 -> PTR_SDOTS -> PTR_SN [style=invis];
+ PTR_S1OPT -> PTR_SOPTDOTS -> PTR_SNOPT [style=invis];
+
TOP -> MEM_TOP;
MEM_TOP -> MEM_ALIAS1;
MEM_TOP -> MEM_ALIAS2;
@@ -106,17 +120,16 @@ digraph Lattice {
MEM_ALIAS1 -> MEM_ALIAS2 -> MEM_ALIASDOTS -> MEM_ALIASN [style=invis];
// Additional customization
- {rank=same; TOP}
- {rank=same; INT_TOP; CTRL; STRUCT_TOP; PTR_TOP; MEM_TOP;}
- {rank=same; PTR_S1; PTR_S2;}
+ {rank=same; TOP;}
+ {rank=same; INT_TOP; XCTRL; STRUCT_TOP; PTR_TOP; MEM_TOP;}
+ {rank=same; PTR_S1; PTR_SDOTS; PTR_SN;}
{rank=same; INT_MIN; INT_MINDOTS;
- INT_MINUS; INT_ZERO;
- INT_PLUS; INT_MAXDOTS;
- INT_MAX; STRUCT_S1; STRUCT_S2;
+ INT_ZERO; INT_MAXDOTS;
+ INT_MAX; TUPLE; STRUCT_S1; STRUCT_DOTS; STRUCT_SN;
PTR_NULL; PTR_VOIDPTR;
MEM_ALIAS1; MEM_ALIAS2;
MEM_ALIASDOTS; MEM_ALIASN;}
- {rank=same; PTR_S1OPT; PTR_S2OPT;}
- {rank=same; INT_BOT; XCTRL; STRUCT_BOT; PTR_BOT; MEM_BOT;}
+ {rank=same; PTR_S1OPT; PTR_SOPTDOTS; PTR_SNOPT; }
+ {rank=same; INT_BOT; CTRL; STRUCT_BOT; PTR_BOT; MEM_BOT;}
{rank=same; BOT;}
} \ No newline at end of file
diff --git a/chapter10/docs/lattice.svg b/chapter10/docs/lattice.svg
index 5ec4bc16..2fe05bbf 100644
--- a/chapter10/docs/lattice.svg
+++ b/chapter10/docs/lattice.svg
@@ -4,457 +4,495 @@
<!-- Generated by graphviz version 2.43.0 (0)
-->
<!-- Title: Lattice Pages: 1 -->
-<svg width="1512pt" height="745pt"
- viewBox="0.00 0.00 1512.20 745.25" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 741.25)">
+<svg width="1694pt" height="771pt"
+ viewBox="0.00 0.00 1694.09 771.25" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 767.25)">
<title>Lattice</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-741.25 1508.2,-741.25 1508.2,4 -4,4"/>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-767.25 1690.09,-767.25 1690.09,4 -4,4"/>
<!-- TOP -->
<g id="node1" class="node">
<title>TOP</title>
-<ellipse fill="lightblue" stroke="black" cx="677.5" cy="-717.76" rx="19.5" ry="19.5"/>
-<text text-anchor="middle" x="677.5" y="-714.06" font-family="Times,serif" font-size="14.00">⊤</text>
+<ellipse fill="lightblue" stroke="black" cx="582.4" cy="-743.75" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="582.4" y="-740.05" font-family="Times,serif" font-size="14.00">⊤</text>
</g>
-<!-- CTRL -->
+<!-- XCTRL -->
<g id="node3" class="node">
-<title>CTRL</title>
-<ellipse fill="lightblue" stroke="black" cx="53.5" cy="-598.56" rx="28.7" ry="28.7"/>
-<text text-anchor="middle" x="53.5" y="-594.86" font-family="Times,serif" font-size="14.00">Ctrl</text>
+<title>XCTRL</title>
+<ellipse fill="lightblue" stroke="black" cx="36.4" cy="-624.56" rx="36.29" ry="36.29"/>
+<text text-anchor="middle" x="36.4" y="-620.86" font-family="Times,serif" font-size="14.00">~Ctrl</text>
</g>
-<!-- TOP&#45;&gt;CTRL -->
+<!-- TOP&#45;&gt;XCTRL -->
<g id="edge1" class="edge">
-<title>TOP&#45;&gt;CTRL</title>
-<path fill="none" stroke="black" d="M658.48,-713.18C568.82,-696.34 188.15,-624.85 81.42,-604.81"/>
+<title>TOP&#45;&gt;XCTRL</title>
+<path fill="none" stroke="black" d="M563.28,-738.65C483.63,-721.55 177.35,-655.81 72.13,-633.23"/>
</g>
<!-- INT_TOP -->
<g id="node5" class="node">
<title>INT_TOP</title>
-<ellipse fill="lightblue" stroke="black" cx="326.5" cy="-598.56" rx="40.09" ry="40.09"/>
-<text text-anchor="middle" x="326.5" y="-594.86" font-family="Times,serif" font-size="14.00">IntTop</text>
+<ellipse fill="lightblue" stroke="black" cx="270.4" cy="-624.56" rx="40.09" ry="40.09"/>
+<text text-anchor="middle" x="270.4" y="-620.86" font-family="Times,serif" font-size="14.00">IntTop</text>
</g>
<!-- TOP&#45;&gt;INT_TOP -->
<g id="edge4" class="edge">
<title>TOP&#45;&gt;INT_TOP</title>
-<path fill="none" stroke="black" d="M659.12,-710.62C604.04,-692.23 439.49,-637.29 364.5,-612.25"/>
+<path fill="none" stroke="black" d="M564.27,-735.95C514.59,-717.28 375.46,-665.02 308,-639.69"/>
+</g>
+<!-- TUPLE -->
+<g id="node12" class="node">
+<title>TUPLE</title>
+<ellipse fill="lightblue" stroke="black" cx="520.4" cy="-386.83" rx="43.59" ry="43.59"/>
+<text text-anchor="middle" x="520.4" y="-383.13" font-family="Times,serif" font-size="14.00">TUPLE</text>
+</g>
+<!-- TOP&#45;&gt;TUPLE -->
+<g id="edge20" class="edge">
+<title>TOP&#45;&gt;TUPLE</title>
+<path fill="none" stroke="black" d="M579.02,-724.31C569.35,-668.67 541.41,-507.81 527.9,-429.99"/>
</g>
<!-- STRUCT_TOP -->
-<g id="node14" class="node">
+<g id="node13" class="node">
<title>STRUCT_TOP</title>
-<ellipse fill="lightblue" stroke="black" cx="677.5" cy="-598.56" rx="36.29" ry="36.29"/>
-<text text-anchor="middle" x="677.5" y="-594.86" font-family="Times,serif" font-size="14.00">$TOP</text>
+<ellipse fill="lightblue" stroke="black" cx="676.4" cy="-624.56" rx="36.29" ry="36.29"/>
+<text text-anchor="middle" x="676.4" y="-620.86" font-family="Times,serif" font-size="14.00">$TOP</text>
</g>
<!-- TOP&#45;&gt;STRUCT_TOP -->
-<g id="edge26" class="edge">
+<g id="edge22" class="edge">
<title>TOP&#45;&gt;STRUCT_TOP</title>
-<path fill="none" stroke="black" d="M677.5,-698.19C677.5,-681.28 677.5,-655.85 677.5,-635.05"/>
+<path fill="none" stroke="black" d="M594.3,-727.91C609.22,-709.31 635.1,-677.04 653.82,-653.7"/>
</g>
<!-- PTR_TOP -->
<g id="node18" class="node">
<title>PTR_TOP</title>
-<ellipse fill="lightblue" stroke="black" cx="909.5" cy="-598.56" rx="40.09" ry="40.09"/>
-<text text-anchor="middle" x="909.5" y="-594.86" font-family="Times,serif" font-size="14.00">*$TOP</text>
+<ellipse fill="lightblue" stroke="black" cx="1045.4" cy="-624.56" rx="40.09" ry="40.09"/>
+<text text-anchor="middle" x="1045.4" y="-620.86" font-family="Times,serif" font-size="14.00">*$TOP</text>
</g>
<!-- TOP&#45;&gt;PTR_TOP -->
<g id="edge32" class="edge">
<title>TOP&#45;&gt;PTR_TOP</title>
-<path fill="none" stroke="black" d="M694.56,-708.14C732.23,-689.11 823.19,-643.16 873.88,-617.56"/>
+<path fill="none" stroke="black" d="M601.12,-738.01C670.15,-720.54 911.28,-659.51 1006.4,-635.43"/>
</g>
<!-- MEM_TOP -->
-<g id="node26" class="node">
+<g id="node28" class="node">
<title>MEM_TOP</title>
-<ellipse fill="lightblue" stroke="black" cx="1289.5" cy="-598.56" rx="63.89" ry="63.89"/>
-<text text-anchor="middle" x="1289.5" y="-594.86" font-family="Times,serif" font-size="14.00">MEM#TOP</text>
+<ellipse fill="lightblue" stroke="black" cx="1471.4" cy="-624.56" rx="63.89" ry="63.89"/>
+<text text-anchor="middle" x="1471.4" y="-620.86" font-family="Times,serif" font-size="14.00">MEM#TOP</text>
</g>
<!-- TOP&#45;&gt;MEM_TOP -->
-<g id="edge48" class="edge">
+<g id="edge57" class="edge">
<title>TOP&#45;&gt;MEM_TOP</title>
-<path fill="none" stroke="black" d="M696.49,-713.12C776.94,-697.71 1091.76,-637.43 1227.1,-611.51"/>
+<path fill="none" stroke="black" d="M601.79,-740.2C708.57,-726.12 1226.52,-657.84 1408.23,-633.89"/>
</g>
<!-- BOT -->
<g id="node2" class="node">
<title>BOT</title>
-<ellipse fill="lightblue" stroke="black" cx="676.5" cy="-19.5" rx="19.5" ry="19.5"/>
-<text text-anchor="middle" x="676.5" y="-15.8" font-family="Times,serif" font-size="14.00">⊥</text>
+<ellipse fill="lightblue" stroke="black" cx="607.4" cy="-19.5" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="607.4" y="-15.8" font-family="Times,serif" font-size="14.00">⊥</text>
</g>
-<!-- XCTRL -->
+<!-- CTRL -->
<g id="node4" class="node">
-<title>XCTRL</title>
-<ellipse fill="lightblue" stroke="black" cx="49.5" cy="-138.69" rx="36.29" ry="36.29"/>
-<text text-anchor="middle" x="49.5" y="-134.99" font-family="Times,serif" font-size="14.00">~Ctrl</text>
+<title>CTRL</title>
+<ellipse fill="lightblue" stroke="black" cx="41.4" cy="-138.69" rx="28.7" ry="28.7"/>
+<text text-anchor="middle" x="41.4" y="-134.99" font-family="Times,serif" font-size="14.00">Ctrl</text>
</g>
-<!-- CTRL&#45;&gt;XCTRL -->
+<!-- XCTRL&#45;&gt;CTRL -->
<g id="edge2" class="edge">
-<title>CTRL&#45;&gt;XCTRL</title>
-<path fill="none" stroke="black" d="M53.25,-569.8C52.55,-489.67 50.59,-264 49.82,-175.22"/>
+<title>XCTRL&#45;&gt;CTRL</title>
+<path fill="none" stroke="black" d="M36.77,-588.04C37.73,-495.13 40.24,-251.2 41.1,-167.42"/>
</g>
-<!-- XCTRL&#45;&gt;BOT -->
+<!-- CTRL&#45;&gt;BOT -->
<g id="edge3" class="edge">
-<title>XCTRL&#45;&gt;BOT</title>
-<path fill="none" stroke="black" d="M85.46,-130.97C202.43,-109.11 569.57,-40.49 657.46,-24.06"/>
+<title>CTRL&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M69.46,-131.88C169.17,-111.23 504.8,-41.74 588.41,-24.43"/>
</g>
<!-- INT_MIN -->
<g id="node7" class="node">
<title>INT_MIN</title>
-<ellipse fill="lightblue" stroke="black" cx="19.5" cy="-373.83" rx="19.5" ry="19.5"/>
-<text text-anchor="middle" x="19.5" y="-370.13" font-family="Times,serif" font-size="14.00">&#45;n</text>
+<ellipse fill="lightblue" stroke="black" cx="49.4" cy="-386.83" rx="19.5" ry="19.5"/>
+<text text-anchor="middle" x="49.4" y="-383.13" font-family="Times,serif" font-size="14.00">&#45;n</text>
</g>
<!-- INT_TOP&#45;&gt;INT_MIN -->
<g id="edge5" class="edge">
<title>INT_TOP&#45;&gt;INT_MIN</title>
-<path fill="none" stroke="black" d="M293.93,-574.72C228.5,-526.83 83.24,-420.49 35.23,-385.35"/>
+<path fill="none" stroke="black" d="M242.85,-594.93C194.95,-543.4 98.03,-439.14 62.68,-401.12"/>
</g>
<!-- INT_MINDOTS -->
<g id="node8" class="node">
<title>INT_MINDOTS</title>
-<text text-anchor="middle" x="108.5" y="-370.13" font-family="Times,serif" font-size="14.00">...</text>
+<text text-anchor="middle" x="138.4" y="-383.13" font-family="Times,serif" font-size="14.00">...</text>
</g>
<!-- INT_TOP&#45;&gt;INT_MINDOTS -->
<g id="edge6" class="edge">
<title>INT_TOP&#45;&gt;INT_MINDOTS</title>
-<path fill="none" stroke="black" d="M298,-569.18C252.29,-522.07 163.93,-430.97 126.23,-392.11"/>
-</g>
-<!-- INT_MINUS -->
-<g id="node9" class="node">
-<title>INT_MINUS</title>
-<ellipse fill="lightblue" stroke="black" cx="197.5" cy="-373.83" rx="19.5" ry="19.5"/>
-<text text-anchor="middle" x="197.5" y="-370.13" font-family="Times,serif" font-size="14.00">&#45;1</text>
-</g>
-<!-- INT_TOP&#45;&gt;INT_MINUS -->
-<g id="edge7" class="edge">
-<title>INT_TOP&#45;&gt;INT_MINUS</title>
-<path fill="none" stroke="black" d="M306.34,-563.45C278.21,-514.44 228.26,-427.43 207.25,-390.81"/>
+<path fill="none" stroke="black" d="M250.78,-589.23C222.27,-537.88 170.4,-444.47 148.54,-405.1"/>
</g>
<!-- INT_ZERO -->
-<g id="node10" class="node">
+<g id="node9" class="node">
<title>INT_ZERO</title>
-<ellipse fill="lightblue" stroke="black" cx="281.5" cy="-373.83" rx="18" ry="18"/>
-<text text-anchor="middle" x="281.5" y="-370.13" font-family="Times,serif" font-size="14.00">0</text>
+<ellipse fill="lightblue" stroke="black" cx="226.4" cy="-386.83" rx="18" ry="18"/>
+<text text-anchor="middle" x="226.4" y="-383.13" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- INT_TOP&#45;&gt;INT_ZERO -->
-<g id="edge8" class="edge">
+<g id="edge7" class="edge">
<title>INT_TOP&#45;&gt;INT_ZERO</title>
-<path fill="none" stroke="black" d="M318.56,-558.9C308.69,-509.63 292.28,-427.68 285.08,-391.7"/>
-</g>
-<!-- INT_PLUS -->
-<g id="node11" class="node">
-<title>INT_PLUS</title>
-<ellipse fill="lightblue" stroke="black" cx="360.5" cy="-373.83" rx="18" ry="18"/>
-<text text-anchor="middle" x="360.5" y="-370.13" font-family="Times,serif" font-size="14.00">1</text>
-</g>
-<!-- INT_TOP&#45;&gt;INT_PLUS -->
-<g id="edge9" class="edge">
-<title>INT_TOP&#45;&gt;INT_PLUS</title>
-<path fill="none" stroke="black" d="M332.54,-558.64C340,-509.33 352.37,-427.55 357.8,-391.65"/>
+<path fill="none" stroke="black" d="M263.03,-584.77C253.34,-532.42 236.73,-442.64 229.69,-404.64"/>
</g>
<!-- INT_MAXDOTS -->
-<g id="node12" class="node">
+<g id="node10" class="node">
<title>INT_MAXDOTS</title>
-<text text-anchor="middle" x="448.5" y="-370.13" font-family="Times,serif" font-size="14.00">...</text>
+<text text-anchor="middle" x="314.4" y="-383.13" font-family="Times,serif" font-size="14.00">...</text>
</g>
<!-- INT_TOP&#45;&gt;INT_MAXDOTS -->
-<g id="edge10" class="edge">
+<g id="edge8" class="edge">
<title>INT_TOP&#45;&gt;INT_MAXDOTS</title>
-<path fill="none" stroke="black" d="M345.83,-562.95C372.23,-514.31 418.59,-428.91 438.72,-391.84"/>
+<path fill="none" stroke="black" d="M277.76,-584.77C287.42,-532.56 303.98,-443.09 311.05,-404.93"/>
</g>
<!-- INT_MAX -->
-<g id="node13" class="node">
+<g id="node11" class="node">
<title>INT_MAX</title>
-<ellipse fill="lightblue" stroke="black" cx="543.5" cy="-373.83" rx="24.9" ry="24.9"/>
-<text text-anchor="middle" x="543.5" y="-370.13" font-family="Times,serif" font-size="14.00">+n</text>
+<ellipse fill="lightblue" stroke="black" cx="409.4" cy="-386.83" rx="24.9" ry="24.9"/>
+<text text-anchor="middle" x="409.4" y="-383.13" font-family="Times,serif" font-size="14.00">+n</text>
</g>
<!-- INT_TOP&#45;&gt;INT_MAX -->
-<g id="edge11" class="edge">
+<g id="edge9" class="edge">
<title>INT_TOP&#45;&gt;INT_MAX</title>
-<path fill="none" stroke="black" d="M354.87,-569.18C400.48,-521.95 488.77,-430.51 526.13,-391.82"/>
+<path fill="none" stroke="black" d="M290.76,-589.74C319.94,-539.83 372.79,-449.44 396.85,-408.28"/>
</g>
<!-- INT_BOT -->
<g id="node6" class="node">
<title>INT_BOT</title>
-<ellipse fill="lightblue" stroke="black" cx="326.5" cy="-138.69" rx="40.09" ry="40.09"/>
-<text text-anchor="middle" x="326.5" y="-134.99" font-family="Times,serif" font-size="14.00">IntBot</text>
+<ellipse fill="lightblue" stroke="black" cx="271.4" cy="-138.69" rx="40.09" ry="40.09"/>
+<text text-anchor="middle" x="271.4" y="-134.99" font-family="Times,serif" font-size="14.00">IntBot</text>
</g>
<!-- INT_BOT&#45;&gt;BOT -->
-<g id="edge19" class="edge">
+<g id="edge15" class="edge">
<title>INT_BOT&#45;&gt;BOT</title>
-<path fill="none" stroke="black" d="M364.62,-124.93C439.56,-99.83 603.55,-44.92 658.3,-26.59"/>
+<path fill="none" stroke="black" d="M309.29,-124.48C381.37,-99.33 535.79,-45.47 588.96,-26.93"/>
</g>
<!-- INT_MIN&#45;&gt;INT_BOT -->
-<g id="edge12" class="edge">
+<g id="edge10" class="edge">
<title>INT_MIN&#45;&gt;INT_BOT</title>
-<path fill="none" stroke="black" d="M35.14,-361.84C83.16,-325.06 229.13,-213.27 294.38,-163.29"/>
+<path fill="none" stroke="black" d="M62.62,-372.05C98.18,-332.3 196.43,-222.49 244.37,-168.9"/>
</g>
<!-- INT_MIN&#45;&gt;INT_MINDOTS -->
<!-- INT_MINDOTS&#45;&gt;INT_BOT -->
-<g id="edge13" class="edge">
+<g id="edge11" class="edge">
<title>INT_MINDOTS&#45;&gt;INT_BOT</title>
-<path fill="none" stroke="black" d="M125.24,-355.77C162.63,-315.44 253.21,-217.74 299.01,-168.34"/>
+<path fill="none" stroke="black" d="M148.18,-368.58C170.07,-327.73 223.37,-228.29 252.17,-174.56"/>
</g>
-<!-- INT_MINDOTS&#45;&gt;INT_MINUS -->
-<!-- INT_MINUS&#45;&gt;INT_BOT -->
-<g id="edge14" class="edge">
-<title>INT_MINUS&#45;&gt;INT_BOT</title>
-<path fill="none" stroke="black" d="M206.98,-356.54C227.99,-318.25 278.79,-225.65 306.93,-174.37"/>
-</g>
-<!-- INT_MINUS&#45;&gt;INT_ZERO -->
+<!-- INT_MINDOTS&#45;&gt;INT_ZERO -->
<!-- INT_ZERO&#45;&gt;INT_BOT -->
-<g id="edge15" class="edge">
+<g id="edge12" class="edge">
<title>INT_ZERO&#45;&gt;INT_BOT</title>
-<path fill="none" stroke="black" d="M284.95,-355.77C292.18,-318.02 309.02,-230.01 318.9,-178.39"/>
+<path fill="none" stroke="black" d="M229.63,-368.98C236.81,-329.42 254.2,-233.54 264.13,-178.78"/>
</g>
-<!-- INT_ZERO&#45;&gt;INT_PLUS -->
-<!-- INT_PLUS&#45;&gt;INT_BOT -->
-<g id="edge16" class="edge">
-<title>INT_PLUS&#45;&gt;INT_BOT</title>
-<path fill="none" stroke="black" d="M357.89,-355.77C352.44,-318.13 339.77,-230.51 332.3,-178.83"/>
-</g>
-<!-- INT_PLUS&#45;&gt;INT_MAXDOTS -->
+<!-- INT_ZERO&#45;&gt;INT_MAXDOTS -->
<!-- INT_MAXDOTS&#45;&gt;INT_BOT -->
-<g id="edge17" class="edge">
+<g id="edge13" class="edge">
<title>INT_MAXDOTS&#45;&gt;INT_BOT</title>
-<path fill="none" stroke="black" d="M439.13,-355.77C419.04,-317.05 371.52,-225.46 345.07,-174.49"/>
+<path fill="none" stroke="black" d="M311.23,-368.58C304.33,-328.74 287.77,-233.16 278.32,-178.61"/>
</g>
<!-- INT_MAXDOTS&#45;&gt;INT_MAX -->
<!-- INT_MAX&#45;&gt;INT_BOT -->
-<g id="edge18" class="edge">
+<g id="edge14" class="edge">
<title>INT_MAX&#45;&gt;INT_BOT</title>
-<path fill="none" stroke="black" d="M526.47,-355.38C489.1,-314.89 399.62,-217.93 354.11,-168.61"/>
+<path fill="none" stroke="black" d="M397.39,-365.24C373.59,-322.44 320.2,-226.45 291.15,-174.21"/>
+</g>
+<!-- TUPLE&#45;&gt;BOT -->
+<g id="edge21" class="edge">
+<title>TUPLE&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M530.46,-344.33C549.34,-264.63 589.36,-95.64 602.85,-38.69"/>
</g>
<!-- STRUCT_S1 -->
-<g id="node15" class="node">
+<g id="node14" class="node">
<title>STRUCT_S1</title>
-<ellipse fill="lightblue" stroke="black" cx="633.5" cy="-373.83" rx="23" ry="23"/>
-<text text-anchor="middle" x="633.5" y="-370.13" font-family="Times,serif" font-size="14.00">S1</text>
+<ellipse fill="lightblue" stroke="black" cx="629.4" cy="-386.83" rx="23" ry="23"/>
+<text text-anchor="middle" x="629.4" y="-383.13" font-family="Times,serif" font-size="14.00">S1</text>
</g>
<!-- STRUCT_TOP&#45;&gt;STRUCT_S1 -->
-<g id="edge27" class="edge">
+<g id="edge23" class="edge">
<title>STRUCT_TOP&#45;&gt;STRUCT_S1</title>
-<path fill="none" stroke="black" d="M670.43,-562.46C661.25,-515.55 645.49,-435.09 637.88,-396.19"/>
+<path fill="none" stroke="black" d="M669.31,-588.71C659.49,-539.03 642.03,-450.71 633.85,-409.35"/>
</g>
-<!-- STRUCT_S2 -->
+<!-- STRUCT_DOTS -->
+<g id="node15" class="node">
+<title>STRUCT_DOTS</title>
+<text text-anchor="middle" x="722.4" y="-383.13" font-family="Times,serif" font-size="14.00">...</text>
+</g>
+<!-- STRUCT_TOP&#45;&gt;STRUCT_DOTS -->
+<g id="edge24" class="edge">
+<title>STRUCT_TOP&#45;&gt;STRUCT_DOTS</title>
+<path fill="none" stroke="black" d="M683.33,-588.71C693.3,-537.22 711.3,-444.2 718.88,-405.01"/>
+</g>
+<!-- STRUCT_SN -->
<g id="node16" class="node">
-<title>STRUCT_S2</title>
-<ellipse fill="lightblue" stroke="black" cx="721.5" cy="-373.83" rx="23" ry="23"/>
-<text text-anchor="middle" x="721.5" y="-370.13" font-family="Times,serif" font-size="14.00">S2</text>
+<title>STRUCT_SN</title>
+<ellipse fill="lightblue" stroke="black" cx="815.4" cy="-386.83" rx="23" ry="23"/>
+<text text-anchor="middle" x="815.4" y="-383.13" font-family="Times,serif" font-size="14.00">Sn</text>
</g>
-<!-- STRUCT_TOP&#45;&gt;STRUCT_S2 -->
-<g id="edge28" class="edge">
-<title>STRUCT_TOP&#45;&gt;STRUCT_S2</title>
-<path fill="none" stroke="black" d="M684.57,-562.46C693.75,-515.55 709.5,-435.09 717.12,-396.19"/>
+<!-- STRUCT_TOP&#45;&gt;STRUCT_SN -->
+<g id="edge25" class="edge">
+<title>STRUCT_TOP&#45;&gt;STRUCT_SN</title>
+<path fill="none" stroke="black" d="M694.85,-592.99C723.95,-543.23 779.65,-447.97 803.78,-406.7"/>
</g>
+<!-- STRUCT_S1&#45;&gt;STRUCT_DOTS -->
<!-- STRUCT_BOT -->
<g id="node17" class="node">
<title>STRUCT_BOT</title>
-<ellipse fill="lightblue" stroke="black" cx="676.5" cy="-138.69" rx="36.29" ry="36.29"/>
-<text text-anchor="middle" x="676.5" y="-134.99" font-family="Times,serif" font-size="14.00">$BOT</text>
+<ellipse fill="lightblue" stroke="black" cx="673.4" cy="-138.69" rx="36.29" ry="36.29"/>
+<text text-anchor="middle" x="673.4" y="-134.99" font-family="Times,serif" font-size="14.00">$BOT</text>
</g>
<!-- STRUCT_S1&#45;&gt;STRUCT_BOT -->
-<g id="edge29" class="edge">
+<g id="edge26" class="edge">
<title>STRUCT_S1&#45;&gt;STRUCT_BOT</title>
-<path fill="none" stroke="black" d="M637.62,-351.28C645.08,-310.47 660.89,-224.05 669.88,-174.89"/>
+<path fill="none" stroke="black" d="M633.38,-364.37C641.02,-321.3 657.78,-226.77 667,-174.76"/>
</g>
-<!-- STRUCT_S2&#45;&gt;STRUCT_BOT -->
-<g id="edge30" class="edge">
-<title>STRUCT_S2&#45;&gt;STRUCT_BOT</title>
-<path fill="none" stroke="black" d="M717.18,-351.28C709.35,-310.36 692.74,-223.57 683.35,-174.47"/>
+<!-- STRUCT_DOTS&#45;&gt;STRUCT_SN -->
+<!-- STRUCT_DOTS&#45;&gt;STRUCT_BOT -->
+<g id="edge27" class="edge">
+<title>STRUCT_DOTS&#45;&gt;STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M718.79,-368.58C710.73,-327.73 691.09,-228.29 680.48,-174.56"/>
+</g>
+<!-- STRUCT_SN&#45;&gt;STRUCT_BOT -->
+<g id="edge28" class="edge">
+<title>STRUCT_SN&#45;&gt;STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M804.02,-366.94C779.47,-324.04 721.36,-222.51 691.62,-170.54"/>
</g>
<!-- STRUCT_BOT&#45;&gt;BOT -->
-<g id="edge31" class="edge">
+<g id="edge29" class="edge">
<title>STRUCT_BOT&#45;&gt;BOT</title>
-<path fill="none" stroke="black" d="M676.5,-102.21C676.5,-81.46 676.5,-56.11 676.5,-39.2"/>
+<path fill="none" stroke="black" d="M655.88,-106.59C643.28,-84.22 626.78,-54.92 616.64,-36.92"/>
</g>
<!-- PTR_NULL -->
<g id="node19" class="node">
<title>PTR_NULL</title>
-<ellipse fill="lightblue" stroke="black" cx="815.5" cy="-373.83" rx="28.7" ry="28.7"/>
-<text text-anchor="middle" x="815.5" y="-370.13" font-family="Times,serif" font-size="14.00">null</text>
+<ellipse fill="lightblue" stroke="black" cx="997.4" cy="-386.83" rx="28.7" ry="28.7"/>
+<text text-anchor="middle" x="997.4" y="-383.13" font-family="Times,serif" font-size="14.00">null</text>
</g>
<!-- PTR_TOP&#45;&gt;PTR_NULL -->
-<g id="edge35" class="edge">
+<g id="edge36" class="edge">
<title>PTR_TOP&#45;&gt;PTR_NULL</title>
-<path fill="none" stroke="black" d="M893.87,-561.2C874.87,-515.77 843.27,-440.23 826.59,-400.36"/>
+<path fill="none" stroke="black" d="M1037.42,-585.04C1027.71,-536.98 1011.58,-457.07 1003.06,-414.89"/>
</g>
<!-- PTR_VOIDPTR -->
<g id="node20" class="node">
<title>PTR_VOIDPTR</title>
-<ellipse fill="lightblue" stroke="black" cx="1008.5" cy="-373.83" rx="34.39" ry="34.39"/>
-<text text-anchor="middle" x="1008.5" y="-370.13" font-family="Times,serif" font-size="14.00">*void</text>
+<ellipse fill="lightblue" stroke="black" cx="1190.4" cy="-386.83" rx="34.39" ry="34.39"/>
+<text text-anchor="middle" x="1190.4" y="-383.13" font-family="Times,serif" font-size="14.00">*void</text>
</g>
<!-- PTR_TOP&#45;&gt;PTR_VOIDPTR -->
-<g id="edge36" class="edge">
+<g id="edge37" class="edge">
<title>PTR_TOP&#45;&gt;PTR_VOIDPTR</title>
-<path fill="none" stroke="black" d="M925.85,-561.45C945.01,-517.94 976.45,-446.57 994.53,-405.54"/>
+<path fill="none" stroke="black" d="M1066.48,-589.99C1094.99,-543.24 1145.36,-460.66 1172.27,-416.55"/>
</g>
<!-- PTR_S1 -->
<g id="node21" class="node">
<title>PTR_S1</title>
-<ellipse fill="lightblue" stroke="black" cx="909.5" cy="-471.57" rx="27.1" ry="27.1"/>
-<text text-anchor="middle" x="909.5" y="-467.87" font-family="Times,serif" font-size="14.00">*S1</text>
+<ellipse fill="lightblue" stroke="black" cx="907.4" cy="-495.62" rx="27.1" ry="27.1"/>
+<text text-anchor="middle" x="907.4" y="-491.92" font-family="Times,serif" font-size="14.00">*S1</text>
</g>
<!-- PTR_TOP&#45;&gt;PTR_S1 -->
<g id="edge33" class="edge">
<title>PTR_TOP&#45;&gt;PTR_S1</title>
-<path fill="none" stroke="black" d="M909.5,-558.01C909.5,-538.85 909.5,-516.34 909.5,-499.23"/>
+<path fill="none" stroke="black" d="M1016.13,-596.64C989.39,-572.04 950.57,-536.33 927.27,-514.9"/>
</g>
-<!-- PTR_S2 -->
+<!-- PTR_SDOTS -->
<g id="node22" class="node">
-<title>PTR_S2</title>
-<ellipse fill="lightblue" stroke="black" cx="1093.5" cy="-471.57" rx="27.1" ry="27.1"/>
-<text text-anchor="middle" x="1093.5" y="-467.87" font-family="Times,serif" font-size="14.00">*S2</text>
+<title>PTR_SDOTS</title>
+<text text-anchor="middle" x="1091.4" y="-491.92" font-family="Times,serif" font-size="14.00">...</text>
</g>
-<!-- PTR_TOP&#45;&gt;PTR_S2 -->
+<!-- PTR_TOP&#45;&gt;PTR_SDOTS -->
<g id="edge34" class="edge">
-<title>PTR_TOP&#45;&gt;PTR_S2</title>
-<path fill="none" stroke="black" d="M942.39,-575.22C979.61,-549.94 1039.19,-509.46 1071.29,-487.66"/>
+<title>PTR_TOP&#45;&gt;PTR_SDOTS</title>
+<path fill="none" stroke="black" d="M1058.83,-586.5C1067.52,-562.5 1078.44,-532.36 1085.17,-513.8"/>
</g>
-<!-- PTR_S1OPT -->
+<!-- PTR_SN -->
<g id="node23" class="node">
+<title>PTR_SN</title>
+<ellipse fill="lightblue" stroke="black" cx="1277.4" cy="-495.62" rx="29.5" ry="29.5"/>
+<text text-anchor="middle" x="1277.4" y="-491.92" font-family="Times,serif" font-size="14.00">*SN</text>
+</g>
+<!-- PTR_TOP&#45;&gt;PTR_SN -->
+<g id="edge35" class="edge">
+<title>PTR_TOP&#45;&gt;PTR_SN</title>
+<path fill="none" stroke="black" d="M1080.38,-604.42C1127.6,-578.58 1210.58,-533.18 1252.16,-510.43"/>
+</g>
+<!-- PTR_S1OPT -->
+<g id="node24" class="node">
<title>PTR_S1OPT</title>
-<ellipse fill="lightblue" stroke="black" cx="904.5" cy="-270.88" rx="32.49" ry="32.49"/>
-<text text-anchor="middle" x="904.5" y="-267.18" font-family="Times,serif" font-size="14.00">*S1?</text>
+<ellipse fill="lightblue" stroke="black" cx="900.4" cy="-272.83" rx="32.49" ry="32.49"/>
+<text text-anchor="middle" x="900.4" y="-269.13" font-family="Times,serif" font-size="14.00">*S1?</text>
</g>
<!-- PTR_NULL&#45;&gt;PTR_S1OPT -->
-<g id="edge38" class="edge">
+<g id="edge39" class="edge">
<title>PTR_NULL&#45;&gt;PTR_S1OPT</title>
-<path fill="none" stroke="black" d="M833.94,-351.91C848.3,-335.63 868.24,-313 883.27,-295.96"/>
+<path fill="none" stroke="black" d="M979.15,-364.76C962.69,-345.75 938.48,-317.8 921.25,-297.91"/>
</g>
-<!-- PTR_S2OPT -->
-<g id="node24" class="node">
-<title>PTR_S2OPT</title>
-<ellipse fill="lightblue" stroke="black" cx="1012.5" cy="-270.88" rx="32.49" ry="32.49"/>
-<text text-anchor="middle" x="1012.5" y="-267.18" font-family="Times,serif" font-size="14.00">*S2?</text>
+<!-- PTR_SOPTDOTS -->
+<g id="node25" class="node">
+<title>PTR_SOPTDOTS</title>
+<text text-anchor="middle" x="1089.4" y="-269.13" font-family="Times,serif" font-size="14.00">...</text>
</g>
-<!-- PTR_NULL&#45;&gt;PTR_S2OPT -->
-<g id="edge39" class="edge">
-<title>PTR_NULL&#45;&gt;PTR_S2OPT</title>
-<path fill="none" stroke="black" d="M840.85,-359.84C877.53,-341.04 945.23,-306.35 983.73,-286.62"/>
+<!-- PTR_NULL&#45;&gt;PTR_SOPTDOTS -->
+<g id="edge40" class="edge">
+<title>PTR_NULL&#45;&gt;PTR_SOPTDOTS</title>
+<path fill="none" stroke="black" d="M1015.14,-364.23C1032.68,-342.87 1059.18,-310.62 1075.32,-290.96"/>
+</g>
+<!-- PTR_SNOPT -->
+<g id="node26" class="node">
+<title>PTR_SNOPT</title>
+<ellipse fill="lightblue" stroke="black" cx="1193.4" cy="-272.83" rx="34.39" ry="34.39"/>
+<text text-anchor="middle" x="1193.4" y="-269.13" font-family="Times,serif" font-size="14.00">*SN?</text>
+</g>
+<!-- PTR_NULL&#45;&gt;PTR_SNOPT -->
+<g id="edge41" class="edge">
+<title>PTR_NULL&#45;&gt;PTR_SNOPT</title>
+<path fill="none" stroke="black" d="M1021.82,-371.87C1057.84,-351.29 1125.11,-312.85 1163.86,-290.71"/>
</g>
<!-- PTR_BOT -->
-<g id="node25" class="node">
+<g id="node27" class="node">
<title>PTR_BOT</title>
-<ellipse fill="lightblue" stroke="black" cx="904.5" cy="-138.69" rx="46.29" ry="46.29"/>
-<text text-anchor="middle" x="904.5" y="-134.99" font-family="Times,serif" font-size="14.00">*$BOT?</text>
+<ellipse fill="lightblue" stroke="black" cx="1043.4" cy="-138.69" rx="46.29" ry="46.29"/>
+<text text-anchor="middle" x="1043.4" y="-134.99" font-family="Times,serif" font-size="14.00">*$BOT?</text>
</g>
<!-- PTR_NULL&#45;&gt;PTR_BOT -->
-<g id="edge37" class="edge">
+<g id="edge38" class="edge">
<title>PTR_NULL&#45;&gt;PTR_BOT</title>
-<path fill="none" stroke="black" d="M825.71,-346.85C840.96,-306.56 869.84,-230.25 888.08,-182.07"/>
+<path fill="none" stroke="black" d="M1002.67,-358.36C1010.56,-315.84 1025.48,-235.32 1034.91,-184.46"/>
</g>
<!-- PTR_VOIDPTR&#45;&gt;PTR_BOT -->
-<g id="edge44" class="edge">
+<g id="edge48" class="edge">
<title>PTR_VOIDPTR&#45;&gt;PTR_BOT</title>
-<path fill="none" stroke="black" d="M994.47,-342.11C976.06,-300.5 943.7,-227.32 923.22,-181.01"/>
+<path fill="none" stroke="black" d="M1172.67,-356.89C1146.24,-312.3 1096.5,-228.33 1067.02,-178.56"/>
</g>
<!-- PTR_S1&#45;&gt;PTR_VOIDPTR -->
-<g id="edge41" class="edge">
+<g id="edge43" class="edge">
<title>PTR_S1&#45;&gt;PTR_VOIDPTR</title>
-<path fill="none" stroke="black" d="M929.06,-451.65C944.84,-436.4 967.12,-414.85 984.07,-398.46"/>
+<path fill="none" stroke="black" d="M933.01,-484.95C984.71,-465.44 1101.45,-421.39 1158.2,-399.97"/>
</g>
+<!-- PTR_S1&#45;&gt;PTR_SDOTS -->
<!-- PTR_S1&#45;&gt;PTR_S1OPT -->
-<g id="edge40" class="edge">
+<g id="edge42" class="edge">
<title>PTR_S1&#45;&gt;PTR_S1OPT</title>
-<path fill="none" stroke="black" d="M908.81,-444.09C907.9,-407.48 906.29,-342.81 905.32,-303.69"/>
+<path fill="none" stroke="black" d="M906.54,-468.3C905.25,-427.17 902.8,-349.47 901.42,-305.44"/>
</g>
-<!-- PTR_S2&#45;&gt;PTR_VOIDPTR -->
-<g id="edge43" class="edge">
-<title>PTR_S2&#45;&gt;PTR_VOIDPTR</title>
-<path fill="none" stroke="black" d="M1075.47,-450.27C1062.51,-435.66 1044.94,-415.87 1031.05,-400.22"/>
+<!-- PTR_SDOTS&#45;&gt;PTR_VOIDPTR -->
+<g id="edge45" class="edge">
+<title>PTR_SDOTS&#45;&gt;PTR_VOIDPTR</title>
+<path fill="none" stroke="black" d="M1107.3,-477.46C1123.48,-460.01 1148.73,-432.78 1167.15,-412.91"/>
</g>
-<!-- PTR_S2&#45;&gt;PTR_S2OPT -->
-<g id="edge42" class="edge">
-<title>PTR_S2&#45;&gt;PTR_S2OPT</title>
-<path fill="none" stroke="black" d="M1083.24,-446.15C1068.34,-409.24 1040.75,-340.89 1024.79,-301.33"/>
+<!-- PTR_SDOTS&#45;&gt;PTR_SN -->
+<!-- PTR_SDOTS&#45;&gt;PTR_SOPTDOTS -->
+<g id="edge44" class="edge">
+<title>PTR_SDOTS&#45;&gt;PTR_SOPTDOTS</title>
+<path fill="none" stroke="black" d="M1091.23,-477.39C1090.86,-435.51 1089.94,-332.83 1089.56,-291"/>
+</g>
+<!-- PTR_SN&#45;&gt;PTR_VOIDPTR -->
+<g id="edge47" class="edge">
+<title>PTR_SN&#45;&gt;PTR_VOIDPTR</title>
+<path fill="none" stroke="black" d="M1259.37,-472.49C1245.53,-455.51 1226.39,-432.01 1211.78,-414.07"/>
</g>
+<!-- PTR_SN&#45;&gt;PTR_SNOPT -->
+<g id="edge46" class="edge">
+<title>PTR_SN&#45;&gt;PTR_SNOPT</title>
+<path fill="none" stroke="black" d="M1266.93,-467.85C1251.36,-426.56 1222.17,-349.14 1205.63,-305.29"/>
+</g>
+<!-- PTR_S1OPT&#45;&gt;PTR_SOPTDOTS -->
<!-- PTR_S1OPT&#45;&gt;PTR_BOT -->
-<g id="edge45" class="edge">
+<g id="edge49" class="edge">
<title>PTR_S1OPT&#45;&gt;PTR_BOT</title>
-<path fill="none" stroke="black" d="M904.5,-238.37C904.5,-222.41 904.5,-202.75 904.5,-185.19"/>
+<path fill="none" stroke="black" d="M924.01,-250.01C947.41,-228.39 983.48,-195.06 1009.85,-170.69"/>
</g>
-<!-- PTR_S2OPT&#45;&gt;PTR_BOT -->
-<g id="edge46" class="edge">
-<title>PTR_S2OPT&#45;&gt;PTR_BOT</title>
-<path fill="none" stroke="black" d="M992.18,-245.39C975.69,-225.51 952.2,-197.2 933.69,-174.88"/>
+<!-- PTR_SOPTDOTS&#45;&gt;PTR_SNOPT -->
+<!-- PTR_SOPTDOTS&#45;&gt;PTR_BOT -->
+<g id="edge50" class="edge">
+<title>PTR_SOPTDOTS&#45;&gt;PTR_BOT</title>
+<path fill="none" stroke="black" d="M1083.48,-254.83C1077.14,-236.63 1066.85,-207.07 1058.28,-182.46"/>
+</g>
+<!-- PTR_SNOPT&#45;&gt;PTR_BOT -->
+<g id="edge51" class="edge">
+<title>PTR_SNOPT&#45;&gt;PTR_BOT</title>
+<path fill="none" stroke="black" d="M1167.95,-249.42C1143.13,-227.55 1105.19,-194.13 1077.71,-169.92"/>
</g>
<!-- PTR_BOT&#45;&gt;BOT -->
-<g id="edge47" class="edge">
+<g id="edge52" class="edge">
<title>PTR_BOT&#45;&gt;BOT</title>
-<path fill="none" stroke="black" d="M863.74,-116.74C813.14,-90.73 729.17,-47.57 693.44,-29.2"/>
+<path fill="none" stroke="black" d="M998.79,-125.7C905.03,-100.5 690.85,-42.93 626.21,-25.56"/>
</g>
<!-- MEM_ALIAS1 -->
-<g id="node27" class="node">
+<g id="node29" class="node">
<title>MEM_ALIAS1</title>
-<ellipse fill="lightblue" stroke="black" cx="1197.5" cy="-373.83" rx="24.9" ry="24.9"/>
-<text text-anchor="middle" x="1197.5" y="-370.13" font-family="Times,serif" font-size="14.00">#1</text>
+<ellipse fill="lightblue" stroke="black" cx="1379.4" cy="-386.83" rx="24.9" ry="24.9"/>
+<text text-anchor="middle" x="1379.4" y="-383.13" font-family="Times,serif" font-size="14.00">#1</text>
</g>
<!-- MEM_TOP&#45;&gt;MEM_ALIAS1 -->
-<g id="edge49" class="edge">
+<g id="edge58" class="edge">
<title>MEM_TOP&#45;&gt;MEM_ALIAS1</title>
-<path fill="none" stroke="black" d="M1265.33,-539.52C1246.21,-492.83 1220.56,-430.15 1206.93,-396.86"/>
+<path fill="none" stroke="black" d="M1448.3,-564.88C1428.87,-514.67 1402.13,-445.56 1388.37,-410.01"/>
</g>
<!-- MEM_ALIAS2 -->
-<g id="node28" class="node">
+<g id="node30" class="node">
<title>MEM_ALIAS2</title>
-<ellipse fill="lightblue" stroke="black" cx="1289.5" cy="-373.83" rx="24.9" ry="24.9"/>
-<text text-anchor="middle" x="1289.5" y="-370.13" font-family="Times,serif" font-size="14.00">#2</text>
+<ellipse fill="lightblue" stroke="black" cx="1471.4" cy="-386.83" rx="24.9" ry="24.9"/>
+<text text-anchor="middle" x="1471.4" y="-383.13" font-family="Times,serif" font-size="14.00">#2</text>
</g>
<!-- MEM_TOP&#45;&gt;MEM_ALIAS2 -->
-<g id="edge50" class="edge">
+<g id="edge59" class="edge">
<title>MEM_TOP&#45;&gt;MEM_ALIAS2</title>
-<path fill="none" stroke="black" d="M1289.5,-534.76C1289.5,-489.47 1289.5,-431.15 1289.5,-398.6"/>
+<path fill="none" stroke="black" d="M1471.4,-560.85C1471.4,-511.89 1471.4,-446.88 1471.4,-411.81"/>
</g>
<!-- MEM_ALIASDOTS -->
-<g id="node29" class="node">
+<g id="node31" class="node">
<title>MEM_ALIASDOTS</title>
-<text text-anchor="middle" x="1384.5" y="-370.13" font-family="Times,serif" font-size="14.00">...</text>
+<text text-anchor="middle" x="1566.4" y="-383.13" font-family="Times,serif" font-size="14.00">...</text>
</g>
<!-- MEM_TOP&#45;&gt;MEM_ALIASDOTS -->
-<g id="edge51" class="edge">
+<g id="edge60" class="edge">
<title>MEM_TOP&#45;&gt;MEM_ALIASDOTS</title>
-<path fill="none" stroke="black" d="M1314.33,-539.81C1335.12,-490.65 1363.46,-423.61 1376.87,-391.88"/>
+<path fill="none" stroke="black" d="M1495.12,-565.18C1516.17,-512.51 1545.61,-438.84 1559.11,-405.06"/>
</g>
<!-- MEM_ALIASN -->
-<g id="node30" class="node">
+<g id="node32" class="node">
<title>MEM_ALIASN</title>
-<ellipse fill="lightblue" stroke="black" cx="1479.5" cy="-373.83" rx="24.9" ry="24.9"/>
-<text text-anchor="middle" x="1479.5" y="-370.13" font-family="Times,serif" font-size="14.00">#n</text>
+<ellipse fill="lightblue" stroke="black" cx="1661.4" cy="-386.83" rx="24.9" ry="24.9"/>
+<text text-anchor="middle" x="1661.4" y="-383.13" font-family="Times,serif" font-size="14.00">#n</text>
</g>
<!-- MEM_TOP&#45;&gt;MEM_ALIASN -->
-<g id="edge52" class="edge">
+<g id="edge61" class="edge">
<title>MEM_TOP&#45;&gt;MEM_ALIASN</title>
-<path fill="none" stroke="black" d="M1330.73,-549.8C1372.31,-500.61 1434.39,-427.19 1463.43,-392.83"/>
+<path fill="none" stroke="black" d="M1511.23,-574.72C1553.01,-522.44 1616.59,-442.89 1645.77,-406.38"/>
</g>
<!-- MEM_ALIAS1&#45;&gt;MEM_ALIAS2 -->
<!-- MEM_BOT -->
-<g id="node31" class="node">
+<g id="node33" class="node">
<title>MEM_BOT</title>
-<ellipse fill="lightblue" stroke="black" cx="1289.5" cy="-138.69" rx="63.89" ry="63.89"/>
-<text text-anchor="middle" x="1289.5" y="-134.99" font-family="Times,serif" font-size="14.00">MEM#BOT</text>
+<ellipse fill="lightblue" stroke="black" cx="1471.4" cy="-138.69" rx="63.89" ry="63.89"/>
+<text text-anchor="middle" x="1471.4" y="-134.99" font-family="Times,serif" font-size="14.00">MEM#BOT</text>
</g>
<!-- MEM_ALIAS1&#45;&gt;MEM_BOT -->
-<g id="edge53" class="edge">
+<g id="edge62" class="edge">
<title>MEM_ALIAS1&#45;&gt;MEM_BOT</title>
-<path fill="none" stroke="black" d="M1206.66,-350.42C1220.43,-315.22 1246.91,-247.53 1266.24,-198.13"/>
+<path fill="none" stroke="black" d="M1388.05,-363.48C1401.92,-326.08 1429.55,-251.56 1449.19,-198.59"/>
</g>
<!-- MEM_ALIAS2&#45;&gt;MEM_ALIASDOTS -->
<!-- MEM_ALIAS2&#45;&gt;MEM_BOT -->
-<g id="edge54" class="edge">
+<g id="edge63" class="edge">
<title>MEM_ALIAS2&#45;&gt;MEM_BOT</title>
-<path fill="none" stroke="black" d="M1289.5,-349.11C1289.5,-314.68 1289.5,-251.08 1289.5,-202.78"/>
+<path fill="none" stroke="black" d="M1471.4,-362.13C1471.4,-325.23 1471.4,-254.49 1471.4,-202.46"/>
</g>
<!-- MEM_ALIASDOTS&#45;&gt;MEM_ALIASN -->
<!-- MEM_ALIASDOTS&#45;&gt;MEM_BOT -->
-<g id="edge55" class="edge">
+<g id="edge64" class="edge">
<title>MEM_ALIASDOTS&#45;&gt;MEM_BOT</title>
-<path fill="none" stroke="black" d="M1377.2,-355.77C1363.73,-322.43 1334.42,-249.88 1313.39,-197.83"/>
+<path fill="none" stroke="black" d="M1559.41,-368.58C1545.87,-333.21 1515.52,-253.93 1494.26,-198.42"/>
</g>
<!-- MEM_ALIASN&#45;&gt;MEM_BOT -->
-<g id="edge56" class="edge">
+<g id="edge65" class="edge">
<title>MEM_ALIASN&#45;&gt;MEM_BOT</title>
-<path fill="none" stroke="black" d="M1463.95,-354.58C1434.88,-318.61 1371.46,-240.12 1329.63,-188.36"/>
+<path fill="none" stroke="black" d="M1646.17,-366.94C1616.93,-328.76 1552.13,-244.12 1510.17,-189.33"/>
</g>
<!-- MEM_BOT&#45;&gt;BOT -->
-<g id="edge57" class="edge">
+<g id="edge66" class="edge">
<title>MEM_BOT&#45;&gt;BOT</title>
-<path fill="none" stroke="black" d="M1227.06,-125.75C1091.6,-99.86 776.38,-39.59 695.62,-24.15"/>
+<path fill="none" stroke="black" d="M1408.21,-129.12C1230.24,-104.98 730.92,-37.25 626.64,-23.11"/>
</g>
</g>
</svg>