summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TypeAnalysis.md84
-rw-r--r--docs/lattice_iffcsp.gv162
-rw-r--r--docs/lattice_iffcsp.svg587
3 files changed, 813 insertions, 20 deletions
diff --git a/TypeAnalysis.md b/TypeAnalysis.md
index 6fff40f9..f2f573ee 100644
--- a/TypeAnalysis.md
+++ b/TypeAnalysis.md
@@ -1,4 +1,4 @@
-# Type Analysis vs Constant Propagation
+# Type Analysis via Constant Propagation
## Prelude
@@ -28,7 +28,7 @@ because the same algorithm is now also *conditional* without any other changes;
SCCP does not require the Sea-of-Nodes, although the presentation is simpler.
More jargon: I use *program points* interchangeably with *nodes in an SSA-based
-IR graph* or sometimes simply *nodes*.
+IR graph* or sometimes simply *nodes*.
## Table of Contents
@@ -38,15 +38,15 @@ IR graph* or sometimes simply *nodes*.
* [A Sample Typing Error](#a-sample-typing-error)
* [Tuples](#tuples)
* [Structs](#structs)
-* Pointers
+* [Pointers](#pointers)
* [Functions](#functions)
* [Type Sugar And All The Rest](#type-sugar-and-all-the-rest)
* [Methods](#methods)
* [Subclassing](#Subclassing)
* [Structural Typing](#structural-typing)
* [Nomative Typing and Traits and Interfaces](#nomative-typing-and-traits-and-interfaces)
-* Conditional Conformance
* Parametric Polymorphism
+* Conditional Conformance
* Call Graph Discovery
* Separate compilation
* Performance Concerns
@@ -278,7 +278,6 @@ but we will shortly use them in building structs and functions.
[Lattice6](./docs/lattice_iffct.svg) <img src = ./docs/lattice_iffct.svg>
-
## Structs
We implement *struct types* as a tuple with named fields:
@@ -308,6 +307,51 @@ I am not covering here how to initialize struct members, or the syntax for
declaring structs or traits - just the resulting types.
+## Pointers
+
+We implement typed pointers as a wrapper over a struct, with extra bits
+for carrying more information depending on the level of precision desired.
+
+[Lattice8](./docs/lattice_iffcsp.svg) <img src = ./docs/lattice_iffcsp.svg>
+
+Tracking null pointers is easy this way, with a simple lattice `{ ⊤, ptr, ptr?, ⊥}` where the `ptr?`
+indicates a pointer which may be null. We can make dereferencing a may-be-null pointer
+safe with a runtime check and an upcast:
+
+```
+val ptr = rand() ? null : Cat("Whiskers"); // Inferred type: *[name:"Whiskers", makeSound=#1{}]?
+
+if( ptr ) // null-check
+ // hidden upcast to drop the null
+ ptr.makeSound() // Legal, because ptr cannot be null
+```
+
+### Equivalence Class Aliasing
+
+The Sea-of-Nodes IR design uses the *equivalence class* model of aliasing,
+where memory is broken up into *equivalence classes*. Pointers point into one
+or another class; pointers in unrelated classes **never** alias, those in the
+same class **always** alias.
+
+This model works really well for strongly typed languages such as Java and
+Simple. I believe it will work well for e.g. mojo as well, although I have not
+tried it. Obviously other models work as well. In this case it is easy to add
+aliasing support in the type system: all pointers have an *alias number*, a unique
+indicator of which *equivalence class* they belong too. Set of aliases are
+possible, often as a using a bitvector.
+
+In the above example with a struct `[myPi: 3.14, result: 17, someFP8: ⊥:FP8]`
+memory is broken up into classes for the `myPi` fields, `result` fields and
+`someFP8` fields, leading to at least 3 alias classes. Pointers to the `myPi`
+fields will never alias with `result` fields because the field names are
+different (also, the core types are different).
+
+Pointer types may also carry information like `raw` or `unsafe`, or pointers
+into e.g. GPU memory (probably as another alias class), or pointers to
+uninitialized memory, or destructed memory.
+
+
+
## Functions
Functions have argument types and some return types (often just 1). We'll
@@ -346,12 +390,12 @@ so e.g. `fcn: [fcn_widen_ascii_char,fcn_narrow_wide_char]{u8 -> u16}`.
Collections of possible functions are easy to track as e.g. a simple bitvector,
with one bit for each function in the program. Other choices also work, such
-as a sparse bitvector when only a few functions are possible in variable in a
+as a sparse bitvector when only a few functions are possible from a
large program with many 1000's of functions. The most common case is a single
function, i.e., just calling a function by name.
A *function index* is simply a unique small integer that refers to a function
-(perhaps via array lookup), and can be effieciently tracked.
+(perhaps via array lookup), and can be efficiently tracked.
The type system will track function collections *in general*, so the general
case is that the function type has a set of allowed functions, and might
@@ -359,7 +403,7 @@ include an indication of the infinite number of functions that might be found
in some external compilation unit.
The reason to track functions this way is that the type system will allow us to
-build a reasonably accurate Call Graph: the set of functions arriving at a call
+build a reasonably accurate Call Graph: the set of function types arriving at a call
site dictates which functions might be called here. More on this in the [Call
Graph](#call-graph) section.
@@ -386,18 +430,18 @@ struct String {
}
```
-In this typing formulation, methods will be struct *fields* that happen to be
-function-typed, or basically as *type sugar* over the existing types already
+In this typing formulation, methods will be struct **fields** that happen to be
+function-typed, or basically as type sugar over the existing types already
mentioned above.
-The `toUpperCase` field here is finally assigned a function constant - and as
+The `toUpperCase` field here is **finally** assigned a function constant - and, as
with all final constant fields, the field value is the same for all instances
of `String` so does not need to be implemented as actually in the `String`
-instances. As an implementation detail, the field can be moved over to some
-collection of such fields, a `class String` instance.
+instances. As an implementation detail, these final field constants can be moved over to some
+collection of such fields, e.g. a `class String` instance.
-From the typing systems point-of-view, however, the field is a full fledged
-member of the `String` type. E.g. some psudeo-definition of `String`:
+From the typing systems point-of-view, the field is a full-fledged
+member of the `String` type. E.g. some pseudo-definition of `String`:
```java
String = : [ // String is a struct type...
@@ -458,7 +502,7 @@ dog = Dog("Spot");
`Cat` is a name for a type `[name:String, makeSound:[#1]{Pet->String}]`,
i.e. its a `Pet` except the `makeSound` field is now typed as a concrete
-function `[#1]`. Similarly for `Dog` and concrete function `[#2]`
+function `[#1]`. Similarly, for `Dog` and concrete function `[#2]`
The instance variable `cat` is typed as `[name:"Whiskers",
makeSound:[#1]{Pet->String}]` which *isa* `Cat`, and similar for `dog` and
@@ -498,7 +542,7 @@ when checking on fields.
We already have structural typing (e.g. static duck-typing) with no further
ado. Here we make a struct type with a single field `quack`, and an infinite
-number of `⊤` fields, meaning we dont care what the other fields are.
+number of `⊤` fields, meaning we don't care what the other fields are.
```
[quack : { self -> String }, ⊤, ⊤, ⊤,,, ]
@@ -535,10 +579,10 @@ here. The requirement is strictly that the passed-in argument has the needed
signature (needs a function-typed `quack` field).
-## Nomative Typing and Traits and Interfaces
+## Nominative Typing and Traits and Interfaces
-Nomative typing is basically structural typing, plus a constraint that we
-*also* match the type name. We add a little *type sugar* to force a failure if
+Nominative typing is basically structural typing, plus a constraint that we
+*also* match the type name. We add a little type sugar to force a failure if
the type names do not match, a hidden field with a funny name:
```
diff --git a/docs/lattice_iffcsp.gv b/docs/lattice_iffcsp.gv
new file mode 100644
index 00000000..c700576e
--- /dev/null
+++ b/docs/lattice_iffcsp.gv
@@ -0,0 +1,162 @@
+digraph Lattice {
+ compound = true;
+ // Define nodes
+ splines=false;
+ node [shape=circle, style=filled];
+ nodesep=0.6;
+
+ TOP [label=<<B>⊤</B >>, fillcolor=black, fontcolor=white];
+ BOT [label=<<B>⊥</B>>, fillcolor=black, fontcolor=white];
+
+ // ----------------------
+ // Control
+ XCTRL [label=<<B>⊤</B >:ctrl>, fillcolor=yellow, shape=oval];
+ CTRL [label=<<B>⊥</B>:ctrl>, fillcolor=yellow, shape=oval];
+
+ TOP -> XCTRL;
+ XCTRL -> CTRL;
+ CTRL -> BOT;
+
+ // ----------------------
+ // Integers
+ INT_TOP [label=<<B>⊤</B >:int>, fillcolor=lightblue, shape=oval];
+ INT_BOT [label=<<B>⊥</B>:int>, fillcolor=lightblue, shape=oval];
+
+ INT_HI [label="max < min" , fillcolor=lightblue, shape=oval];
+ INT_XBOOL [label="1...0", fillcolor=lightblue, shape=oval];
+ INT_CON [label="constants...", fillcolor=lightblue, shape=oval];
+ INT_CON0 [label="0", fillcolor=lightblue];
+ INT_CON1 [label="1", fillcolor=lightblue];
+ INT_BOOL [label="0...1", fillcolor=lightblue,shape=oval];
+ INT_LO [label="max > min" , fillcolor=lightblue, shape=oval];
+
+ TOP -> INT_TOP;
+ INT_TOP -> INT_HI;
+ INT_HI -> INT_XBOOL;
+ INT_XBOOL -> INT_CON0;
+ INT_XBOOL -> INT_CON1;
+ INT_HI -> INT_CON;
+ INT_CON0 -> INT_BOOL;
+ INT_CON1 -> INT_BOOL;
+ INT_BOOL -> INT_LO;
+ INT_CON -> INT_LO;
+ INT_LO -> INT_BOT;
+ INT_BOT -> BOT;
+
+ INT_CON0 -> INT_CON1 -> INT_CON [style=invis];
+
+ // ----------------------
+ // Floats
+ FLT_TOP [label=<<B>⊤</B >:flt>, fillcolor=aqua, shape=oval];
+ FLT_BOT [label=<<B>⊥</B>:flt>, fillcolor=aqua, shape=oval];
+
+ FLT_CON64 [label="64b consts\n[excludes\n32b consts]" , fillcolor=aqua, shape=oval];
+ FLT_CON32 [label="32b consts", fillcolor=aqua, shape=oval];
+ FLT_CONPI [label="3.14159...", fillcolor=aqua, shape=oval];
+ FLT_X32 [label="~f32", fillcolor=aqua];
+ FLT_CON0 [label="0." , fillcolor=aqua];
+ FLT_32 [label="f32" , fillcolor=aqua];
+
+ TOP -> FLT_TOP;
+ FLT_TOP -> FLT_CON64
+ FLT_TOP -> FLT_CONPI
+ FLT_CON64 -> FLT_BOT
+ FLT_CONPI -> FLT_BOT
+
+ FLT_TOP -> FLT_X32;
+ FLT_X32 -> FLT_CON0;
+ FLT_X32 -> FLT_CON32;
+ FLT_CON0 -> FLT_32;
+ FLT_CON32 -> FLT_32;
+ FLT_32 -> FLT_BOT
+
+ FLT_BOT -> BOT;
+
+ FLT_CON0 -> FLT_CON32 -> FLT_CONPI -> FLT_CON64 [style=invis];
+
+ // ----------------------
+ // sub-Floats
+ FL8_TOP [label=<<B>⊤</B >:FP8>, fillcolor=aqua, shape=oval];
+ FL8_BOT [label=<<B>⊥</B>:FP8>, fillcolor=aqua, shape=oval];
+
+ FL8_MINDOTS [label="...", fillcolor=aqua, shape=oval];
+ FL8_ZERO [label="0" , fillcolor=aqua];
+ FL8_MAXDOTS [label="...", fillcolor=aqua, shape=oval];
+
+ TOP -> FL8_TOP;
+ FL8_TOP -> FL8_MINDOTS;
+ FL8_TOP -> FL8_ZERO;
+ FL8_TOP -> FL8_MAXDOTS;
+ FL8_MINDOTS -> FL8_BOT;
+ FL8_ZERO -> FL8_BOT;
+ FL8_MAXDOTS -> FL8_BOT;
+ FL8_BOT -> BOT;
+
+ FL8_MINDOTS -> FL8_ZERO -> FL8_MAXDOTS [style=invis];
+
+ // ----------------------
+ // Structs
+ STRUCT_TOP [label=<<B>⊤</B >:struct>, fillcolor=lightgreen, shape=oval];
+ STRUCT_BOT [label=<<B>⊥</B>:struct>, fillcolor=lightgreen, shape=oval];
+
+ STRUCT_S1 [shape=none, fillcolor=none, label=<
+ <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
+ <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR>
+ </TABLE>
+ >];
+ STRUCT_S2 [shape=none, fillcolor=none, label=<
+ <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
+ <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR>
+ <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR>
+ </TABLE>
+ >];
+ STRUCT_SN [shape=none, fillcolor=none, label=<
+ <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
+ <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR>
+ <TR><TD BGCOLOR="lightgreen">... </TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR>
+ <TR><TD BGCOLOR="lightgreen">field</TD><TD BGCOLOR="lightblue:green" gradientangle="315">int/ptr</TD></TR>
+ </TABLE>
+ >];
+
+
+ TOP -> STRUCT_TOP;
+ STRUCT_TOP -> STRUCT_S1;
+ STRUCT_TOP -> STRUCT_S2;
+ STRUCT_TOP -> STRUCT_SN;
+ STRUCT_S1 -> STRUCT_BOT;
+ STRUCT_S2 -> STRUCT_BOT;
+ STRUCT_SN -> STRUCT_BOT;
+ STRUCT_BOT -> BOT;
+
+ STRUCT_S1 -> STRUCT_S2 -> STRUCT_SN [style=invis];
+
+ // ----------------------
+ // Pointers, just a boolean nil/not and a struct
+ PTR [shape=none, fillcolor=none, label=<
+ <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
+ <TR><TD BGCOLOR="green"><FONT color="white">*ptr</FONT></TD></TR>
+ <TR><TD BGCOLOR="lightgreen">struct</TD></TR>
+ </TABLE>
+ >];
+ PTR0 [shape=none, fillcolor=none, label=<
+ <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
+ <TR><TD BGCOLOR="green"><FONT color="white">*ptr?</FONT></TD></TR>
+ <TR><TD BGCOLOR="lightgreen">struct</TD></TR>
+ </TABLE>
+ >];
+
+ TOP -> PTR;
+ PTR -> PTR0;
+ PTR0 -> BOT;
+
+ // Additional customization
+ {rank=same; TOP}
+ {rank=same; INT_TOP; FLT_TOP; FL8_TOP; XCTRL }
+ {rank=same; INT_CON; INT_CON0; INT_CON1;
+ FLT_CON32; FLT_CON64; FLT_CON0; FLT_CONPI;
+ FL8_MINDOTS; FL8_ZERO; FL8_MAXDOTS;
+ STRUCT_S1; STRUCT_S2; STRUCT_SN;
+ }
+ {rank=same; INT_BOT; FLT_BOT; FL8_BOT; STRUCT_BOT; PTR0; CTRL; }
+ {rank=same; BOT;}
+}
diff --git a/docs/lattice_iffcsp.svg b/docs/lattice_iffcsp.svg
new file mode 100644
index 00000000..12de199d
--- /dev/null
+++ b/docs/lattice_iffcsp.svg
@@ -0,0 +1,587 @@
+<?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 12.2.0 (20241103.1931)
+ -->
+<!-- Title: Lattice Pages: 1 -->
+<svg width="1510pt" height="743pt"
+ viewBox="0.00 0.00 1509.51 742.86" 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 738.86)">
+<title>Lattice</title>
+<polygon fill="white" stroke="none" points="-4,4 -4,-738.86 1505.51,-738.86 1505.51,4 -4,4"/>
+<!-- TOP -->
+<g id="node1" class="node">
+<title>TOP</title>
+<ellipse fill="black" stroke="black" cx="790.51" cy="-713.73" rx="21.12" ry="21.12"/>
+<text text-anchor="start" x="782.63" y="-709.31" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00" fill="white">⊤</text>
+</g>
+<!-- XCTRL -->
+<g id="node3" class="node">
+<title>XCTRL</title>
+<ellipse fill="yellow" stroke="black" cx="36.51" cy="-638.61" rx="36.51" ry="18"/>
+<text text-anchor="start" x="17.76" y="-634.56" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="33.51" y="-634.56" font-family="Times New Roman,serif" font-size="14.00">:ctrl</text>
+</g>
+<!-- TOP&#45;&gt;XCTRL -->
+<g id="edge1" class="edge">
+<title>TOP&#45;&gt;XCTRL</title>
+<path fill="none" stroke="black" d="M769.16,-710.66C667.19,-700.77 228.74,-658.25 83.47,-644.16"/>
+<polygon fill="black" stroke="black" points="84.12,-640.71 73.83,-643.23 83.45,-647.68 84.12,-640.71"/>
+</g>
+<!-- INT_TOP -->
+<g id="node5" class="node">
+<title>INT_TOP</title>
+<ellipse fill="lightblue" stroke="black" cx="433.51" cy="-638.61" rx="33.95" ry="18"/>
+<text text-anchor="start" x="416.63" y="-634.56" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="432.38" y="-634.56" font-family="Times New Roman,serif" font-size="14.00">:int</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="M769.77,-708.49C712.8,-696.82 553.02,-664.09 476.03,-648.32"/>
+<polygon fill="black" stroke="black" points="476.83,-644.91 466.34,-646.33 475.43,-651.77 476.83,-644.91"/>
+</g>
+<!-- FLT_TOP -->
+<g id="node14" class="node">
+<title>FLT_TOP</title>
+<ellipse fill="aqua" stroke="black" cx="684.51" cy="-638.61" rx="32.41" ry="18"/>
+<text text-anchor="start" x="668.76" y="-634.56" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="684.51" y="-634.56" font-family="Times New Roman,serif" font-size="14.00">:flt</text>
+</g>
+<!-- TOP&#45;&gt;FLT_TOP -->
+<g id="edge18" class="edge">
+<title>TOP&#45;&gt;FLT_TOP</title>
+<path fill="none" stroke="black" d="M773.48,-700.99C757.36,-689.86 732.83,-672.94 713.61,-659.68"/>
+<polygon fill="black" stroke="black" points="715.85,-656.98 705.63,-654.18 711.88,-662.74 715.85,-656.98"/>
+</g>
+<!-- FL8_TOP -->
+<g id="node22" class="node">
+<title>FL8_TOP</title>
+<ellipse fill="aqua" stroke="black" cx="926.51" cy="-638.61" rx="39.07" ry="18"/>
+<text text-anchor="start" x="905.88" y="-634.56" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="921.63" y="-634.56" font-family="Times New Roman,serif" font-size="14.00">:FP8</text>
+</g>
+<!-- TOP&#45;&gt;FL8_TOP -->
+<g id="edge33" class="edge">
+<title>TOP&#45;&gt;FL8_TOP</title>
+<path fill="none" stroke="black" d="M808.85,-702.87C830.1,-691.45 865.58,-672.37 892.03,-658.15"/>
+<polygon fill="black" stroke="black" points="893.55,-661.3 900.7,-653.49 890.23,-655.14 893.55,-661.3"/>
+</g>
+<!-- STRUCT_TOP -->
+<g id="node27" class="node">
+<title>STRUCT_TOP</title>
+<ellipse fill="lightgreen" stroke="black" cx="1260.51" cy="-467.29" rx="44.7" ry="18"/>
+<text text-anchor="start" x="1235.76" y="-463.24" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊤</text>
+<text text-anchor="start" x="1251.51" y="-463.24" font-family="Times New Roman,serif" font-size="14.00">:struct</text>
+</g>
+<!-- TOP&#45;&gt;STRUCT_TOP -->
+<g id="edge43" class="edge">
+<title>TOP&#45;&gt;STRUCT_TOP</title>
+<path fill="none" stroke="black" d="M809.52,-703.77C880.03,-666.79 1127.5,-537.03 1222.75,-487.09"/>
+<polygon fill="black" stroke="black" points="1224.23,-490.26 1231.46,-482.52 1220.98,-484.06 1224.23,-490.26"/>
+</g>
+<!-- PTR -->
+<g id="node32" class="node">
+<title>PTR</title>
+<polygon fill="none" stroke="none" points="1451.51,-584.61 1397.51,-584.61 1397.51,-531.61 1451.51,-531.61 1451.51,-584.61"/>
+<polygon fill="green" stroke="none" points="1406.51,-558.11 1406.51,-580.61 1442.51,-580.61 1442.51,-558.11 1406.51,-558.11"/>
+<polygon fill="none" stroke="black" points="1406.51,-558.11 1406.51,-580.61 1442.51,-580.61 1442.51,-558.11 1406.51,-558.11"/>
+<text text-anchor="start" x="1413.63" y="-564.31" font-family="Times New Roman,serif" font-size="14.00" fill="white">*ptr</text>
+<polygon fill="lightgreen" stroke="none" points="1406.51,-535.61 1406.51,-558.11 1442.51,-558.11 1442.51,-535.61 1406.51,-535.61"/>
+<polygon fill="none" stroke="black" points="1406.51,-535.61 1406.51,-558.11 1442.51,-558.11 1442.51,-535.61 1406.51,-535.61"/>
+<text text-anchor="start" x="1409.51" y="-541.81" font-family="Times New Roman,serif" font-size="14.00">struct</text>
+</g>
+<!-- TOP&#45;&gt;PTR -->
+<g id="edge53" class="edge">
+<title>TOP&#45;&gt;PTR</title>
+<path fill="none" stroke="black" d="M811.24,-708.64C902.32,-686.29 1267.68,-596.61 1386.77,-567.37"/>
+<polygon fill="black" stroke="black" points="1387.48,-570.8 1396.36,-565.02 1385.81,-564 1387.48,-570.8"/>
+</g>
+<!-- BOT -->
+<g id="node2" class="node">
+<title>BOT</title>
+<ellipse fill="black" stroke="black" cx="803.51" cy="-21.12" rx="21.12" ry="21.12"/>
+<text text-anchor="start" x="795.63" y="-16.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00" fill="white">⊥</text>
+</g>
+<!-- CTRL -->
+<g id="node4" class="node">
+<title>CTRL</title>
+<ellipse fill="yellow" stroke="black" cx="122.51" cy="-104.75" rx="36.51" ry="18"/>
+<text text-anchor="start" x="103.76" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="119.51" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:ctrl</text>
+</g>
+<!-- XCTRL&#45;&gt;CTRL -->
+<g id="edge2" class="edge">
+<title>XCTRL&#45;&gt;CTRL</title>
+<path fill="none" stroke="black" d="M39.47,-620.23C52.16,-541.46 102.02,-231.93 117.74,-134.37"/>
+<polygon fill="black" stroke="black" points="121.19,-134.97 119.32,-124.54 114.27,-133.86 121.19,-134.97"/>
+</g>
+<!-- CTRL&#45;&gt;BOT -->
+<g id="edge3" class="edge">
+<title>CTRL&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M157.69,-99.53C275.81,-85.37 657.21,-39.66 771.1,-26.01"/>
+<polygon fill="black" stroke="black" points="771.45,-29.49 780.96,-24.83 770.61,-22.54 771.45,-29.49"/>
+</g>
+<!-- INT_HI -->
+<g id="node7" class="node">
+<title>INT_HI</title>
+<ellipse fill="lightblue" stroke="black" cx="242.51" cy="-558.11" rx="52.89" ry="18"/>
+<text text-anchor="middle" x="242.51" y="-553.06" font-family="Times New Roman,serif" font-size="14.00">max &lt; min</text>
+</g>
+<!-- INT_TOP&#45;&gt;INT_HI -->
+<g id="edge5" class="edge">
+<title>INT_TOP&#45;&gt;INT_HI</title>
+<path fill="none" stroke="black" d="M407.35,-626.86C376.11,-614.02 323.38,-592.35 285.98,-576.97"/>
+<polygon fill="black" stroke="black" points="287.36,-573.76 276.78,-573.2 284.7,-580.24 287.36,-573.76"/>
+</g>
+<!-- INT_BOT -->
+<g id="node6" class="node">
+<title>INT_BOT</title>
+<ellipse fill="lightblue" stroke="black" cx="460.51" cy="-104.75" rx="33.95" ry="18"/>
+<text text-anchor="start" x="443.63" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="459.38" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:int</text>
+</g>
+<!-- INT_BOT&#45;&gt;BOT -->
+<g id="edge15" class="edge">
+<title>INT_BOT&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M491.25,-96.43C556.09,-81 706.27,-45.26 771.88,-29.65"/>
+<polygon fill="black" stroke="black" points="772.36,-33.14 781.28,-27.41 770.74,-26.33 772.36,-33.14"/>
+</g>
+<!-- INT_XBOOL -->
+<g id="node8" class="node">
+<title>INT_XBOOL</title>
+<ellipse fill="lightblue" stroke="black" cx="128.51" cy="-467.29" rx="27.81" ry="18"/>
+<text text-anchor="middle" x="128.51" y="-462.24" font-family="Times New Roman,serif" font-size="14.00">1...0</text>
+</g>
+<!-- INT_HI&#45;&gt;INT_XBOOL -->
+<g id="edge6" class="edge">
+<title>INT_HI&#45;&gt;INT_XBOOL</title>
+<path fill="none" stroke="black" d="M222.13,-541.23C203.25,-526.52 175.06,-504.56 154.56,-488.58"/>
+<polygon fill="black" stroke="black" points="156.97,-486.03 146.93,-482.64 152.67,-491.55 156.97,-486.03"/>
+</g>
+<!-- INT_CON -->
+<g id="node9" class="node">
+<title>INT_CON</title>
+<ellipse fill="lightblue" stroke="black" cx="242.51" cy="-362.31" rx="52.89" ry="18"/>
+<text text-anchor="middle" x="242.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">constants...</text>
+</g>
+<!-- INT_HI&#45;&gt;INT_CON -->
+<g id="edge9" class="edge">
+<title>INT_HI&#45;&gt;INT_CON</title>
+<path fill="none" stroke="black" d="M242.51,-539.69C242.51,-505.71 242.51,-432.91 242.51,-391.92"/>
+<polygon fill="black" stroke="black" points="246.01,-392.05 242.51,-382.05 239.01,-392.05 246.01,-392.05"/>
+</g>
+<!-- INT_CON0 -->
+<g id="node10" class="node">
+<title>INT_CON0</title>
+<ellipse fill="lightblue" stroke="black" cx="49.51" cy="-362.31" rx="18" ry="18"/>
+<text text-anchor="middle" x="49.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">0</text>
+</g>
+<!-- INT_XBOOL&#45;&gt;INT_CON0 -->
+<g id="edge7" class="edge">
+<title>INT_XBOOL&#45;&gt;INT_CON0</title>
+<path fill="none" stroke="black" d="M116.51,-450.65C103.31,-433.44 81.96,-405.61 66.91,-386"/>
+<polygon fill="black" stroke="black" points="69.88,-384.12 61.02,-378.32 64.33,-388.38 69.88,-384.12"/>
+</g>
+<!-- INT_CON1 -->
+<g id="node11" class="node">
+<title>INT_CON1</title>
+<ellipse fill="lightblue" stroke="black" cx="128.51" cy="-362.31" rx="18" ry="18"/>
+<text text-anchor="middle" x="128.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">1</text>
+</g>
+<!-- INT_XBOOL&#45;&gt;INT_CON1 -->
+<g id="edge8" class="edge">
+<title>INT_XBOOL&#45;&gt;INT_CON1</title>
+<path fill="none" stroke="black" d="M128.51,-448.82C128.51,-433.27 128.51,-410.22 128.51,-391.97"/>
+<polygon fill="black" stroke="black" points="132.01,-392.04 128.51,-382.04 125.01,-392.04 132.01,-392.04"/>
+</g>
+<!-- INT_LO -->
+<g id="node13" class="node">
+<title>INT_LO</title>
+<ellipse fill="lightblue" stroke="black" cx="242.51" cy="-185.25" rx="52.89" ry="18"/>
+<text text-anchor="middle" x="242.51" y="-180.2" font-family="Times New Roman,serif" font-size="14.00">max &gt; min</text>
+</g>
+<!-- INT_CON&#45;&gt;INT_LO -->
+<g id="edge13" class="edge">
+<title>INT_CON&#45;&gt;INT_LO</title>
+<path fill="none" stroke="black" d="M242.51,-344.03C242.51,-313.55 242.51,-252.05 242.51,-215.18"/>
+<polygon fill="black" stroke="black" points="246.01,-215.21 242.51,-205.21 239.01,-215.21 246.01,-215.21"/>
+</g>
+<!-- INT_CON0&#45;&gt;INT_CON1 -->
+<!-- INT_BOOL -->
+<g id="node12" class="node">
+<title>INT_BOOL</title>
+<ellipse fill="lightblue" stroke="black" cx="128.51" cy="-262.45" rx="27.81" ry="18"/>
+<text text-anchor="middle" x="128.51" y="-257.4" font-family="Times New Roman,serif" font-size="14.00">0...1</text>
+</g>
+<!-- INT_CON0&#45;&gt;INT_BOOL -->
+<g id="edge10" class="edge">
+<title>INT_CON0&#45;&gt;INT_BOOL</title>
+<path fill="none" stroke="black" d="M60.49,-347.7C72.97,-332.25 93.57,-306.73 108.84,-287.81"/>
+<polygon fill="black" stroke="black" points="111.55,-290.03 115.11,-280.05 106.1,-285.64 111.55,-290.03"/>
+</g>
+<!-- INT_CON1&#45;&gt;INT_CON -->
+<!-- INT_CON1&#45;&gt;INT_BOOL -->
+<g id="edge11" class="edge">
+<title>INT_CON1&#45;&gt;INT_BOOL</title>
+<path fill="none" stroke="black" d="M128.51,-343.82C128.51,-329.48 128.51,-308.91 128.51,-292.16"/>
+<polygon fill="black" stroke="black" points="132.01,-292.31 128.51,-282.31 125.01,-292.31 132.01,-292.31"/>
+</g>
+<!-- INT_BOOL&#45;&gt;INT_LO -->
+<g id="edge12" class="edge">
+<title>INT_BOOL&#45;&gt;INT_LO</title>
+<path fill="none" stroke="black" d="M147.59,-248.86C164.48,-237.72 189.49,-221.22 209.6,-207.96"/>
+<polygon fill="black" stroke="black" points="211.34,-211.01 217.76,-202.58 207.48,-205.16 211.34,-211.01"/>
+</g>
+<!-- INT_LO&#45;&gt;INT_BOT -->
+<g id="edge14" class="edge">
+<title>INT_LO&#45;&gt;INT_BOT</title>
+<path fill="none" stroke="black" d="M278.02,-171.46C317.7,-157.17 381.69,-134.13 422.39,-119.47"/>
+<polygon fill="black" stroke="black" points="423.32,-122.86 431.54,-116.18 420.95,-116.27 423.32,-122.86"/>
+</g>
+<!-- FLT_CON64 -->
+<g id="node16" class="node">
+<title>FLT_CON64</title>
+<ellipse fill="aqua" stroke="black" cx="756.51" cy="-362.31" rx="55.33" ry="40.66"/>
+<text text-anchor="middle" x="756.51" y="-373.76" font-family="Times New Roman,serif" font-size="14.00">64b consts</text>
+<text text-anchor="middle" x="756.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">[excludes</text>
+<text text-anchor="middle" x="756.51" y="-340.76" font-family="Times New Roman,serif" font-size="14.00">32b consts]</text>
+</g>
+<!-- FLT_TOP&#45;&gt;FLT_CON64 -->
+<g id="edge19" class="edge">
+<title>FLT_TOP&#45;&gt;FLT_CON64</title>
+<path fill="none" stroke="black" d="M689.23,-620.48C700.03,-579.03 726.86,-476.08 743.19,-413.43"/>
+<polygon fill="black" stroke="black" points="746.49,-414.62 745.63,-404.06 739.72,-412.86 746.49,-414.62"/>
+</g>
+<!-- FLT_CONPI -->
+<g id="node18" class="node">
+<title>FLT_CONPI</title>
+<ellipse fill="aqua" stroke="black" cx="609.51" cy="-362.31" rx="48.79" ry="18"/>
+<text text-anchor="middle" x="609.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">3.14159...</text>
+</g>
+<!-- FLT_TOP&#45;&gt;FLT_CONPI -->
+<g id="edge20" class="edge">
+<title>FLT_TOP&#45;&gt;FLT_CONPI</title>
+<path fill="none" stroke="black" d="M679.59,-620.48C666.87,-573.64 632.85,-448.29 617.37,-391.27"/>
+<polygon fill="black" stroke="black" points="620.84,-390.7 614.84,-381.97 614.09,-392.53 620.84,-390.7"/>
+</g>
+<!-- FLT_X32 -->
+<g id="node19" class="node">
+<title>FLT_X32</title>
+<ellipse fill="aqua" stroke="black" cx="467.51" cy="-467.29" rx="28.32" ry="28.32"/>
+<text text-anchor="middle" x="467.51" y="-462.24" font-family="Times New Roman,serif" font-size="14.00">~f32</text>
+</g>
+<!-- FLT_TOP&#45;&gt;FLT_X32 -->
+<g id="edge23" class="edge">
+<title>FLT_TOP&#45;&gt;FLT_X32</title>
+<path fill="none" stroke="black" d="M665.63,-623.71C628.3,-594.23 544.69,-528.23 498.93,-492.09"/>
+<polygon fill="black" stroke="black" points="501.24,-489.46 491.22,-486.01 496.9,-494.95 501.24,-489.46"/>
+</g>
+<!-- FLT_BOT -->
+<g id="node15" class="node">
+<title>FLT_BOT</title>
+<ellipse fill="aqua" stroke="black" cx="682.51" cy="-104.75" rx="32.41" ry="18"/>
+<text text-anchor="start" x="666.76" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="682.51" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:flt</text>
+</g>
+<!-- FLT_BOT&#45;&gt;BOT -->
+<g id="edge29" class="edge">
+<title>FLT_BOT&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M702.49,-90.27C722.84,-76.54 754.5,-55.18 776.95,-40.04"/>
+<polygon fill="black" stroke="black" points="778.66,-43.11 784.99,-34.62 774.74,-37.31 778.66,-43.11"/>
+</g>
+<!-- FLT_CON64&#45;&gt;FLT_BOT -->
+<g id="edge21" class="edge">
+<title>FLT_CON64&#45;&gt;FLT_BOT</title>
+<path fill="none" stroke="black" d="M744.95,-322.07C729.95,-269.88 704.15,-180.08 690.9,-133.96"/>
+<polygon fill="black" stroke="black" points="694.29,-133.06 688.16,-124.42 687.56,-134.99 694.29,-133.06"/>
+</g>
+<!-- FLT_CON32 -->
+<g id="node17" class="node">
+<title>FLT_CON32</title>
+<ellipse fill="aqua" stroke="black" cx="467.51" cy="-362.31" rx="50.33" ry="18"/>
+<text text-anchor="middle" x="467.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">32b consts</text>
+</g>
+<!-- FLT_CON32&#45;&gt;FLT_CONPI -->
+<!-- FLT_32 -->
+<g id="node21" class="node">
+<title>FLT_32</title>
+<ellipse fill="aqua" stroke="black" cx="467.51" cy="-262.45" rx="23.2" ry="23.2"/>
+<text text-anchor="middle" x="467.51" y="-257.4" font-family="Times New Roman,serif" font-size="14.00">f32</text>
+</g>
+<!-- FLT_CON32&#45;&gt;FLT_32 -->
+<g id="edge27" class="edge">
+<title>FLT_CON32&#45;&gt;FLT_32</title>
+<path fill="none" stroke="black" d="M467.51,-343.82C467.51,-330.94 467.51,-313.02 467.51,-297.37"/>
+<polygon fill="black" stroke="black" points="471.01,-297.47 467.51,-287.47 464.01,-297.47 471.01,-297.47"/>
+</g>
+<!-- FLT_CONPI&#45;&gt;FLT_BOT -->
+<g id="edge22" class="edge">
+<title>FLT_CONPI&#45;&gt;FLT_BOT</title>
+<path fill="none" stroke="black" d="M614.64,-344.2C627.13,-300.14 659.18,-187.07 674.33,-133.6"/>
+<polygon fill="black" stroke="black" points="677.61,-134.87 676.97,-124.3 670.87,-132.96 677.61,-134.87"/>
+</g>
+<!-- FLT_CONPI&#45;&gt;FLT_CON64 -->
+<!-- FLT_X32&#45;&gt;FLT_CON32 -->
+<g id="edge25" class="edge">
+<title>FLT_X32&#45;&gt;FLT_CON32</title>
+<path fill="none" stroke="black" d="M467.51,-438.69C467.51,-424.26 467.51,-406.62 467.51,-392.03"/>
+<polygon fill="black" stroke="black" points="471.01,-392.14 467.51,-382.14 464.01,-392.14 471.01,-392.14"/>
+</g>
+<!-- FLT_CON0 -->
+<g id="node20" class="node">
+<title>FLT_CON0</title>
+<ellipse fill="aqua" stroke="black" cx="356.51" cy="-362.31" rx="18.08" ry="18.08"/>
+<text text-anchor="middle" x="356.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">0.</text>
+</g>
+<!-- FLT_X32&#45;&gt;FLT_CON0 -->
+<g id="edge24" class="edge">
+<title>FLT_X32&#45;&gt;FLT_CON0</title>
+<path fill="none" stroke="black" d="M446.89,-447.16C427.21,-428.9 397.69,-401.51 377.79,-383.05"/>
+<polygon fill="black" stroke="black" points="380.21,-380.53 370.5,-376.29 375.45,-385.66 380.21,-380.53"/>
+</g>
+<!-- FLT_CON0&#45;&gt;FLT_CON32 -->
+<!-- FLT_CON0&#45;&gt;FLT_32 -->
+<g id="edge26" class="edge">
+<title>FLT_CON0&#45;&gt;FLT_32</title>
+<path fill="none" stroke="black" d="M369.68,-349.7C387.42,-334.06 419.38,-305.88 441.93,-286"/>
+<polygon fill="black" stroke="black" points="444.04,-288.81 449.23,-279.57 439.41,-283.56 444.04,-288.81"/>
+</g>
+<!-- FLT_32&#45;&gt;FLT_BOT -->
+<g id="edge28" class="edge">
+<title>FLT_32&#45;&gt;FLT_BOT</title>
+<path fill="none" stroke="black" d="M486.59,-248.46C524.31,-220.79 608.65,-158.93 653.37,-126.12"/>
+<polygon fill="black" stroke="black" points="655.32,-129.03 661.32,-120.29 651.18,-123.38 655.32,-129.03"/>
+</g>
+<!-- FL8_MINDOTS -->
+<g id="node24" class="node">
+<title>FL8_MINDOTS</title>
+<ellipse fill="aqua" stroke="black" cx="881.51" cy="-362.31" rx="27" ry="18"/>
+<text text-anchor="middle" x="881.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">...</text>
+</g>
+<!-- FL8_TOP&#45;&gt;FL8_MINDOTS -->
+<g id="edge34" class="edge">
+<title>FL8_TOP&#45;&gt;FL8_MINDOTS</title>
+<path fill="none" stroke="black" d="M923.56,-620.48C915.94,-573.74 895.6,-448.82 886.28,-391.63"/>
+<polygon fill="black" stroke="black" points="889.78,-391.31 884.72,-382 882.87,-392.43 889.78,-391.31"/>
+</g>
+<!-- FL8_ZERO -->
+<g id="node25" class="node">
+<title>FL8_ZERO</title>
+<ellipse fill="aqua" stroke="black" cx="969.51" cy="-362.31" rx="18" ry="18"/>
+<text text-anchor="middle" x="969.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">0</text>
+</g>
+<!-- FL8_TOP&#45;&gt;FL8_ZERO -->
+<g id="edge35" class="edge">
+<title>FL8_TOP&#45;&gt;FL8_ZERO</title>
+<path fill="none" stroke="black" d="M929.33,-620.48C936.6,-573.74 956.05,-448.82 964.95,-391.63"/>
+<polygon fill="black" stroke="black" points="968.36,-392.42 966.44,-382 961.45,-391.34 968.36,-392.42"/>
+</g>
+<!-- FL8_MAXDOTS -->
+<g id="node26" class="node">
+<title>FL8_MAXDOTS</title>
+<ellipse fill="aqua" stroke="black" cx="1057.51" cy="-362.31" rx="27" ry="18"/>
+<text text-anchor="middle" x="1057.51" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">...</text>
+</g>
+<!-- FL8_TOP&#45;&gt;FL8_MAXDOTS -->
+<g id="edge36" class="edge">
+<title>FL8_TOP&#45;&gt;FL8_MAXDOTS</title>
+<path fill="none" stroke="black" d="M934.9,-620.91C957.09,-574.12 1017.4,-446.91 1044.28,-390.22"/>
+<polygon fill="black" stroke="black" points="1047.41,-391.77 1048.54,-381.24 1041.09,-388.77 1047.41,-391.77"/>
+</g>
+<!-- FL8_BOT -->
+<g id="node23" class="node">
+<title>FL8_BOT</title>
+<ellipse fill="aqua" stroke="black" cx="925.51" cy="-104.75" rx="39.07" ry="18"/>
+<text text-anchor="start" x="904.88" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="920.63" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:FP8</text>
+</g>
+<!-- FL8_BOT&#45;&gt;BOT -->
+<g id="edge40" class="edge">
+<title>FL8_BOT&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M903.98,-89.34C883.45,-75.61 852.48,-54.89 830.35,-40.09"/>
+<polygon fill="black" stroke="black" points="832.4,-37.24 822.14,-34.59 828.5,-43.06 832.4,-37.24"/>
+</g>
+<!-- FL8_MINDOTS&#45;&gt;FL8_BOT -->
+<g id="edge37" class="edge">
+<title>FL8_MINDOTS&#45;&gt;FL8_BOT</title>
+<path fill="none" stroke="black" d="M884.6,-344.2C892.1,-300.34 911.27,-188.09 920.46,-134.33"/>
+<polygon fill="black" stroke="black" points="923.87,-135.12 922.1,-124.68 916.97,-133.94 923.87,-135.12"/>
+</g>
+<!-- FL8_MINDOTS&#45;&gt;FL8_ZERO -->
+<!-- FL8_ZERO&#45;&gt;FL8_BOT -->
+<g id="edge38" class="edge">
+<title>FL8_ZERO&#45;&gt;FL8_BOT</title>
+<path fill="none" stroke="black" d="M966.41,-344.2C958.92,-300.34 939.75,-188.09 930.56,-134.33"/>
+<polygon fill="black" stroke="black" points="934.05,-133.94 928.91,-124.68 927.15,-135.12 934.05,-133.94"/>
+</g>
+<!-- FL8_ZERO&#45;&gt;FL8_MAXDOTS -->
+<!-- FL8_MAXDOTS&#45;&gt;FL8_BOT -->
+<g id="edge39" class="edge">
+<title>FL8_MAXDOTS&#45;&gt;FL8_BOT</title>
+<path fill="none" stroke="black" d="M1048.64,-345.01C1026.25,-301.33 967.27,-186.24 939.88,-132.78"/>
+<polygon fill="black" stroke="black" points="943.05,-131.3 935.38,-124 936.82,-134.5 943.05,-131.3"/>
+</g>
+<!-- STRUCT_S1 -->
+<g id="node29" class="node">
+<title>STRUCT_S1</title>
+<polygon fill="none" stroke="none" points="1213.38,-380.31 1127.63,-380.31 1127.63,-344.31 1213.38,-344.31 1213.38,-380.31"/>
+<polygon fill="lightgreen" stroke="none" points="1135.63,-351.06 1135.63,-373.56 1166.38,-373.56 1166.38,-351.06 1135.63,-351.06"/>
+<polygon fill="none" stroke="black" points="1135.63,-351.06 1135.63,-373.56 1166.38,-373.56 1166.38,-351.06 1135.63,-351.06"/>
+<text text-anchor="start" x="1138.63" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_0" gradientUnits="userSpaceOnUse" x1="1172.1" y1="-370.27" x2="1199.67" y2="-354.36" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_0)" stroke="none" points="1166.38,-351.06 1166.38,-373.56 1205.38,-373.56 1205.38,-351.06 1166.38,-351.06"/>
+<polygon fill="none" stroke="black" points="1166.38,-351.06 1166.38,-373.56 1205.38,-373.56 1205.38,-351.06 1166.38,-351.06"/>
+<text text-anchor="start" x="1169.38" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+</g>
+<!-- STRUCT_TOP&#45;&gt;STRUCT_S1 -->
+<g id="edge44" class="edge">
+<title>STRUCT_TOP&#45;&gt;STRUCT_S1</title>
+<path fill="none" stroke="black" d="M1246.45,-450.2C1232.02,-433.69 1209.37,-407.78 1192.56,-388.54"/>
+<polygon fill="black" stroke="black" points="1195.28,-386.34 1186.07,-381.11 1190.01,-390.94 1195.28,-386.34"/>
+</g>
+<!-- STRUCT_S2 -->
+<g id="node30" class="node">
+<title>STRUCT_S2</title>
+<polygon fill="none" stroke="none" points="1342.38,-388.81 1256.63,-388.81 1256.63,-335.81 1342.38,-335.81 1342.38,-388.81"/>
+<polygon fill="lightgreen" stroke="none" points="1264.63,-362.31 1264.63,-384.81 1295.38,-384.81 1295.38,-362.31 1264.63,-362.31"/>
+<polygon fill="none" stroke="black" points="1264.63,-362.31 1264.63,-384.81 1295.38,-384.81 1295.38,-362.31 1264.63,-362.31"/>
+<text text-anchor="start" x="1267.63" y="-368.51" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_1" gradientUnits="userSpaceOnUse" x1="1301.1" y1="-381.52" x2="1328.67" y2="-365.61" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_1)" stroke="none" points="1295.38,-362.31 1295.38,-384.81 1334.38,-384.81 1334.38,-362.31 1295.38,-362.31"/>
+<polygon fill="none" stroke="black" points="1295.38,-362.31 1295.38,-384.81 1334.38,-384.81 1334.38,-362.31 1295.38,-362.31"/>
+<text text-anchor="start" x="1298.38" y="-368.51" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+<polygon fill="lightgreen" stroke="none" points="1264.63,-339.81 1264.63,-362.31 1295.38,-362.31 1295.38,-339.81 1264.63,-339.81"/>
+<polygon fill="none" stroke="black" points="1264.63,-339.81 1264.63,-362.31 1295.38,-362.31 1295.38,-339.81 1264.63,-339.81"/>
+<text text-anchor="start" x="1267.63" y="-346.01" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_2" gradientUnits="userSpaceOnUse" x1="1301.1" y1="-359.02" x2="1328.67" y2="-343.11" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_2)" stroke="none" points="1295.38,-339.81 1295.38,-362.31 1334.38,-362.31 1334.38,-339.81 1295.38,-339.81"/>
+<polygon fill="none" stroke="black" points="1295.38,-339.81 1295.38,-362.31 1334.38,-362.31 1334.38,-339.81 1295.38,-339.81"/>
+<text text-anchor="start" x="1298.38" y="-346.01" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+</g>
+<!-- STRUCT_TOP&#45;&gt;STRUCT_S2 -->
+<g id="edge45" class="edge">
+<title>STRUCT_TOP&#45;&gt;STRUCT_S2</title>
+<path fill="none" stroke="black" d="M1266.95,-449.28C1272.1,-435.69 1279.49,-416.17 1285.93,-399.17"/>
+<polygon fill="black" stroke="black" points="1289.19,-400.45 1289.46,-389.86 1282.64,-397.97 1289.19,-400.45"/>
+</g>
+<!-- STRUCT_SN -->
+<g id="node31" class="node">
+<title>STRUCT_SN</title>
+<polygon fill="none" stroke="none" points="1471.38,-400.06 1385.63,-400.06 1385.63,-324.56 1471.38,-324.56 1471.38,-400.06"/>
+<polygon fill="lightgreen" stroke="none" points="1393.63,-373.56 1393.63,-396.06 1424.38,-396.06 1424.38,-373.56 1393.63,-373.56"/>
+<polygon fill="none" stroke="black" points="1393.63,-373.56 1393.63,-396.06 1424.38,-396.06 1424.38,-373.56 1393.63,-373.56"/>
+<text text-anchor="start" x="1396.63" y="-379.76" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_3" gradientUnits="userSpaceOnUse" x1="1430.1" y1="-392.77" x2="1457.67" y2="-376.86" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_3)" stroke="none" points="1424.38,-373.56 1424.38,-396.06 1463.38,-396.06 1463.38,-373.56 1424.38,-373.56"/>
+<polygon fill="none" stroke="black" points="1424.38,-373.56 1424.38,-396.06 1463.38,-396.06 1463.38,-373.56 1424.38,-373.56"/>
+<text text-anchor="start" x="1427.38" y="-379.76" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+<polygon fill="lightgreen" stroke="none" points="1393.63,-351.06 1393.63,-373.56 1424.38,-373.56 1424.38,-351.06 1393.63,-351.06"/>
+<polygon fill="none" stroke="black" points="1393.63,-351.06 1393.63,-373.56 1424.38,-373.56 1424.38,-351.06 1393.63,-351.06"/>
+<text text-anchor="start" x="1399.63" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">... &#160;</text>
+<defs>
+<linearGradient id="l_4" gradientUnits="userSpaceOnUse" x1="1430.1" y1="-370.27" x2="1457.67" y2="-354.36" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_4)" stroke="none" points="1424.38,-351.06 1424.38,-373.56 1463.38,-373.56 1463.38,-351.06 1424.38,-351.06"/>
+<polygon fill="none" stroke="black" points="1424.38,-351.06 1424.38,-373.56 1463.38,-373.56 1463.38,-351.06 1424.38,-351.06"/>
+<text text-anchor="start" x="1427.38" y="-357.26" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+<polygon fill="lightgreen" stroke="none" points="1393.63,-328.56 1393.63,-351.06 1424.38,-351.06 1424.38,-328.56 1393.63,-328.56"/>
+<polygon fill="none" stroke="black" points="1393.63,-328.56 1393.63,-351.06 1424.38,-351.06 1424.38,-328.56 1393.63,-328.56"/>
+<text text-anchor="start" x="1396.63" y="-334.76" font-family="Times New Roman,serif" font-size="14.00">field</text>
+<defs>
+<linearGradient id="l_5" gradientUnits="userSpaceOnUse" x1="1430.1" y1="-347.77" x2="1457.67" y2="-331.86" >
+<stop offset="0" style="stop-color:lightblue;stop-opacity:1.;"/>
+<stop offset="1" style="stop-color:green;stop-opacity:1.;"/>
+</linearGradient>
+</defs>
+<polygon fill="url(#l_5)" stroke="none" points="1424.38,-328.56 1424.38,-351.06 1463.38,-351.06 1463.38,-328.56 1424.38,-328.56"/>
+<polygon fill="none" stroke="black" points="1424.38,-328.56 1424.38,-351.06 1463.38,-351.06 1463.38,-328.56 1424.38,-328.56"/>
+<text text-anchor="start" x="1427.38" y="-334.76" font-family="Times New Roman,serif" font-size="14.00">int/ptr</text>
+</g>
+<!-- STRUCT_TOP&#45;&gt;STRUCT_SN -->
+<g id="edge46" class="edge">
+<title>STRUCT_TOP&#45;&gt;STRUCT_SN</title>
+<path fill="none" stroke="black" d="M1284.22,-451.75C1307.97,-437.2 1345.31,-414.31 1376.06,-395.46"/>
+<polygon fill="black" stroke="black" points="1377.79,-398.5 1384.49,-390.29 1374.13,-392.54 1377.79,-398.5"/>
+</g>
+<!-- STRUCT_BOT -->
+<g id="node28" class="node">
+<title>STRUCT_BOT</title>
+<ellipse fill="lightgreen" stroke="black" cx="1234.51" cy="-104.75" rx="44.7" ry="18"/>
+<text text-anchor="start" x="1209.76" y="-100.7" font-family="Times New Roman,serif" font-weight="bold" font-size="14.00">⊥</text>
+<text text-anchor="start" x="1225.51" y="-100.7" font-family="Times New Roman,serif" font-size="14.00">:struct</text>
+</g>
+<!-- STRUCT_BOT&#45;&gt;BOT -->
+<g id="edge50" class="edge">
+<title>STRUCT_BOT&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M1194.73,-96.22C1109.9,-80.15 912.63,-42.79 835.36,-28.16"/>
+<polygon fill="black" stroke="black" points="836.41,-24.79 825.93,-26.37 835.1,-31.67 836.41,-24.79"/>
+</g>
+<!-- STRUCT_S1&#45;&gt;STRUCT_BOT -->
+<g id="edge47" class="edge">
+<title>STRUCT_S1&#45;&gt;STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M1174.91,-344.61C1185.75,-300.97 1213.85,-187.89 1227.23,-134.06"/>
+<polygon fill="black" stroke="black" points="1230.61,-134.94 1229.63,-124.39 1223.82,-133.25 1230.61,-134.94"/>
+</g>
+<!-- STRUCT_S1&#45;&gt;STRUCT_S2 -->
+<!-- STRUCT_S2&#45;&gt;STRUCT_BOT -->
+<g id="edge48" class="edge">
+<title>STRUCT_S2&#45;&gt;STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M1292.92,-336.2C1280.73,-287.89 1254.73,-184.89 1241.94,-134.19"/>
+<polygon fill="black" stroke="black" points="1245.34,-133.37 1239.5,-124.53 1238.55,-135.08 1245.34,-133.37"/>
+</g>
+<!-- STRUCT_S2&#45;&gt;STRUCT_SN -->
+<!-- STRUCT_SN&#45;&gt;STRUCT_BOT -->
+<g id="edge49" class="edge">
+<title>STRUCT_SN&#45;&gt;STRUCT_BOT</title>
+<path fill="none" stroke="black" d="M1400.09,-324.58C1360.3,-271.75 1288.98,-177.06 1254.39,-131.15"/>
+<polygon fill="black" stroke="black" points="1257.32,-129.22 1248.51,-123.33 1251.73,-133.43 1257.32,-129.22"/>
+</g>
+<!-- PTR0 -->
+<g id="node33" class="node">
+<title>PTR0</title>
+<polygon fill="none" stroke="none" points="1501.51,-131.25 1447.51,-131.25 1447.51,-78.25 1501.51,-78.25 1501.51,-131.25"/>
+<polygon fill="green" stroke="none" points="1456.51,-104.75 1456.51,-127.25 1492.51,-127.25 1492.51,-104.75 1456.51,-104.75"/>
+<polygon fill="none" stroke="black" points="1456.51,-104.75 1456.51,-127.25 1492.51,-127.25 1492.51,-104.75 1456.51,-104.75"/>
+<text text-anchor="start" x="1460.63" y="-110.95" font-family="Times New Roman,serif" font-size="14.00" fill="white">*ptr?</text>
+<polygon fill="lightgreen" stroke="none" points="1456.51,-82.25 1456.51,-104.75 1492.51,-104.75 1492.51,-82.25 1456.51,-82.25"/>
+<polygon fill="none" stroke="black" points="1456.51,-82.25 1456.51,-104.75 1492.51,-104.75 1492.51,-82.25 1456.51,-82.25"/>
+<text text-anchor="start" x="1459.51" y="-88.45" font-family="Times New Roman,serif" font-size="14.00">struct</text>
+</g>
+<!-- PTR&#45;&gt;PTR0 -->
+<g id="edge54" class="edge">
+<title>PTR&#45;&gt;PTR0</title>
+<path fill="none" stroke="black" d="M1427.41,-531.78C1435.87,-455.09 1460.5,-231.73 1470.36,-142.36"/>
+<polygon fill="black" stroke="black" points="1473.81,-142.98 1471.43,-132.66 1466.86,-142.22 1473.81,-142.98"/>
+</g>
+<!-- PTR0&#45;&gt;BOT -->
+<g id="edge55" class="edge">
+<title>PTR0&#45;&gt;BOT</title>
+<path fill="none" stroke="black" d="M1447.79,-100.5C1341.85,-87.61 951.52,-40.13 835.95,-26.07"/>
+<polygon fill="black" stroke="black" points="836.59,-22.62 826.24,-24.89 835.74,-29.57 836.59,-22.62"/>
+</g>
+</g>
+</svg>