typesea 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -6
- package/README.md +98 -17
- package/dist/adapters/index.d.ts +50 -8
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +169 -48
- package/dist/aot/index.d.ts +18 -2
- package/dist/aot/index.d.ts.map +1 -1
- package/dist/aot/index.js +93 -14
- package/dist/async/index.d.ts +28 -56
- package/dist/async/index.d.ts.map +1 -1
- package/dist/async/index.js +94 -37
- package/dist/builders/composite.d.ts +37 -6
- package/dist/builders/composite.d.ts.map +1 -1
- package/dist/builders/composite.js +84 -10
- package/dist/builders/index.d.ts +2 -0
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +2 -0
- package/dist/builders/modifier.d.ts +30 -5
- package/dist/builders/modifier.d.ts.map +1 -1
- package/dist/builders/modifier.js +38 -5
- package/dist/builders/object/guard.d.ts +18 -22
- package/dist/builders/object/guard.d.ts.map +1 -1
- package/dist/builders/object/guard.js +26 -26
- package/dist/builders/object/index.d.ts +2 -0
- package/dist/builders/object/index.d.ts.map +1 -1
- package/dist/builders/object/index.js +2 -0
- package/dist/builders/object/schema.d.ts +55 -9
- package/dist/builders/object/schema.d.ts.map +1 -1
- package/dist/builders/object/schema.js +92 -15
- package/dist/builders/object/types.d.ts +5 -31
- package/dist/builders/object/types.d.ts.map +1 -1
- package/dist/builders/object/types.js +2 -0
- package/dist/builders/scalar.d.ts +29 -8
- package/dist/builders/scalar.d.ts.map +1 -1
- package/dist/builders/scalar.js +33 -8
- package/dist/builders/table.d.ts +4 -0
- package/dist/builders/table.d.ts.map +1 -1
- package/dist/builders/table.js +4 -0
- package/dist/builders/types.d.ts +14 -4
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +2 -0
- package/dist/compile/check-composite.d.ts +22 -1
- package/dist/compile/check-composite.d.ts.map +1 -1
- package/dist/compile/check-composite.js +564 -24
- package/dist/compile/check-scalar.d.ts +78 -0
- package/dist/compile/check-scalar.d.ts.map +1 -1
- package/dist/compile/check-scalar.js +432 -1
- package/dist/compile/check.d.ts +12 -0
- package/dist/compile/check.d.ts.map +1 -1
- package/dist/compile/check.js +37 -0
- package/dist/compile/context.d.ts +47 -9
- package/dist/compile/context.d.ts.map +1 -1
- package/dist/compile/context.js +51 -8
- package/dist/compile/graph-predicate.d.ts +4 -2
- package/dist/compile/graph-predicate.d.ts.map +1 -1
- package/dist/compile/graph-predicate.js +1907 -171
- package/dist/compile/guard.d.ts +15 -24
- package/dist/compile/guard.d.ts.map +1 -1
- package/dist/compile/guard.js +158 -74
- package/dist/compile/index.d.ts +3 -1
- package/dist/compile/index.d.ts.map +1 -1
- package/dist/compile/index.js +2 -0
- package/dist/compile/issue.d.ts +110 -0
- package/dist/compile/issue.d.ts.map +1 -1
- package/dist/compile/issue.js +184 -1
- package/dist/compile/names.d.ts +12 -2
- package/dist/compile/names.d.ts.map +1 -1
- package/dist/compile/names.js +19 -3
- package/dist/compile/predicate.d.ts +24 -0
- package/dist/compile/predicate.d.ts.map +1 -1
- package/dist/compile/predicate.js +131 -5
- package/dist/compile/runtime.d.ts +80 -12
- package/dist/compile/runtime.d.ts.map +1 -1
- package/dist/compile/runtime.js +25 -6
- package/dist/compile/source.d.ts +10 -2
- package/dist/compile/source.d.ts.map +1 -1
- package/dist/compile/source.js +361 -26
- package/dist/compile/types.d.ts +20 -0
- package/dist/compile/types.d.ts.map +1 -1
- package/dist/compile/types.js +2 -0
- package/dist/decoder/index.d.ts +32 -46
- package/dist/decoder/index.d.ts.map +1 -1
- package/dist/decoder/index.js +102 -38
- package/dist/evaluate/check-composite.d.ts +59 -0
- package/dist/evaluate/check-composite.d.ts.map +1 -1
- package/dist/evaluate/check-composite.js +151 -3
- package/dist/evaluate/check-scalar.d.ts +16 -0
- package/dist/evaluate/check-scalar.d.ts.map +1 -1
- package/dist/evaluate/check-scalar.js +32 -0
- package/dist/evaluate/check.d.ts +7 -0
- package/dist/evaluate/check.d.ts.map +1 -1
- package/dist/evaluate/check.js +43 -0
- package/dist/evaluate/index.d.ts +2 -0
- package/dist/evaluate/index.d.ts.map +1 -1
- package/dist/evaluate/index.js +2 -0
- package/dist/evaluate/issue.d.ts +11 -1
- package/dist/evaluate/issue.d.ts.map +1 -1
- package/dist/evaluate/issue.js +15 -1
- package/dist/evaluate/predicate.d.ts +16 -5
- package/dist/evaluate/predicate.d.ts.map +1 -1
- package/dist/evaluate/predicate.js +20 -5
- package/dist/evaluate/shared.d.ts +59 -13
- package/dist/evaluate/shared.d.ts.map +1 -1
- package/dist/evaluate/shared.js +66 -8
- package/dist/evaluate/state.d.ts +35 -13
- package/dist/evaluate/state.d.ts.map +1 -1
- package/dist/evaluate/state.js +35 -2
- package/dist/guard/base.d.ts +79 -29
- package/dist/guard/base.d.ts.map +1 -1
- package/dist/guard/base.js +91 -29
- package/dist/guard/error.d.ts +10 -5
- package/dist/guard/error.d.ts.map +1 -1
- package/dist/guard/error.js +10 -5
- package/dist/guard/index.d.ts +2 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +2 -0
- package/dist/guard/number.d.ts +26 -11
- package/dist/guard/number.d.ts.map +1 -1
- package/dist/guard/number.js +30 -11
- package/dist/guard/props.d.ts +27 -3
- package/dist/guard/props.d.ts.map +1 -1
- package/dist/guard/props.js +27 -3
- package/dist/guard/read.d.ts +62 -9
- package/dist/guard/read.d.ts.map +1 -1
- package/dist/guard/read.js +83 -10
- package/dist/guard/registry.d.ts +12 -2
- package/dist/guard/registry.d.ts.map +1 -1
- package/dist/guard/registry.js +15 -3
- package/dist/guard/string.d.ts +33 -13
- package/dist/guard/string.d.ts.map +1 -1
- package/dist/guard/string.js +37 -13
- package/dist/guard/types.d.ts +92 -40
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/guard/types.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/index.d.ts +42 -6
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +51 -8
- package/dist/ir/builder.d.ts +16 -126
- package/dist/ir/builder.d.ts.map +1 -1
- package/dist/ir/builder.js +77 -137
- package/dist/ir/freeze.d.ts +4 -0
- package/dist/ir/freeze.d.ts.map +1 -1
- package/dist/ir/freeze.js +59 -0
- package/dist/ir/index.d.ts +3 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +2 -0
- package/dist/ir/regexp.d.ts +2 -0
- package/dist/ir/regexp.d.ts.map +1 -1
- package/dist/ir/regexp.js +2 -0
- package/dist/ir/types.d.ts +90 -55
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +2 -0
- package/dist/ir/validate.d.ts +8 -1
- package/dist/ir/validate.d.ts.map +1 -1
- package/dist/ir/validate.js +477 -61
- package/dist/issue/index.d.ts +41 -9
- package/dist/issue/index.d.ts.map +1 -1
- package/dist/issue/index.js +61 -11
- package/dist/json-schema/emit-combinator.d.ts +44 -4
- package/dist/json-schema/emit-combinator.d.ts.map +1 -1
- package/dist/json-schema/emit-combinator.js +44 -4
- package/dist/json-schema/emit-composite.d.ts +10 -0
- package/dist/json-schema/emit-composite.d.ts.map +1 -1
- package/dist/json-schema/emit-composite.js +15 -1
- package/dist/json-schema/emit-scalar.d.ts +26 -3
- package/dist/json-schema/emit-scalar.d.ts.map +1 -1
- package/dist/json-schema/emit-scalar.js +70 -9
- package/dist/json-schema/emit-types.d.ts +11 -1
- package/dist/json-schema/emit-types.d.ts.map +1 -1
- package/dist/json-schema/emit-types.js +2 -0
- package/dist/json-schema/emit.d.ts +12 -1
- package/dist/json-schema/emit.d.ts.map +1 -1
- package/dist/json-schema/emit.js +12 -1
- package/dist/json-schema/freeze.d.ts +13 -2
- package/dist/json-schema/freeze.d.ts.map +1 -1
- package/dist/json-schema/freeze.js +41 -8
- package/dist/json-schema/index.d.ts +16 -2
- package/dist/json-schema/index.d.ts.map +1 -1
- package/dist/json-schema/index.js +23 -3
- package/dist/json-schema/issue.d.ts +4 -1
- package/dist/json-schema/issue.d.ts.map +1 -1
- package/dist/json-schema/issue.js +4 -1
- package/dist/json-schema/read.d.ts +24 -3
- package/dist/json-schema/read.d.ts.map +1 -1
- package/dist/json-schema/read.js +59 -12
- package/dist/json-schema/types.d.ts +38 -15
- package/dist/json-schema/types.d.ts.map +1 -1
- package/dist/json-schema/types.js +2 -0
- package/dist/kind/index.d.ts +15 -28
- package/dist/kind/index.d.ts.map +1 -1
- package/dist/kind/index.js +15 -10
- package/dist/lower/index.d.ts +6 -1
- package/dist/lower/index.d.ts.map +1 -1
- package/dist/lower/index.js +411 -44
- package/dist/message/index.d.ts +46 -10
- package/dist/message/index.d.ts.map +1 -1
- package/dist/message/index.js +88 -17
- package/dist/optimize/algebraic.d.ts +54 -0
- package/dist/optimize/algebraic.d.ts.map +1 -0
- package/dist/optimize/algebraic.js +314 -0
- package/dist/optimize/compact.d.ts +8 -1
- package/dist/optimize/compact.d.ts.map +1 -1
- package/dist/optimize/compact.js +13 -2
- package/dist/optimize/domain.d.ts +16 -0
- package/dist/optimize/domain.d.ts.map +1 -0
- package/dist/optimize/domain.js +615 -0
- package/dist/optimize/fold-boolean.d.ts +17 -2
- package/dist/optimize/fold-boolean.d.ts.map +1 -1
- package/dist/optimize/fold-boolean.js +59 -14
- package/dist/optimize/fold-common.d.ts +43 -8
- package/dist/optimize/fold-common.d.ts.map +1 -1
- package/dist/optimize/fold-common.js +37 -6
- package/dist/optimize/fold-constraints.d.ts +33 -0
- package/dist/optimize/fold-constraints.d.ts.map +1 -0
- package/dist/optimize/fold-constraints.js +484 -0
- package/dist/optimize/fold-scalar.d.ts +98 -13
- package/dist/optimize/fold-scalar.d.ts.map +1 -1
- package/dist/optimize/fold-scalar.js +98 -13
- package/dist/optimize/fold.d.ts +8 -1
- package/dist/optimize/fold.d.ts.map +1 -1
- package/dist/optimize/fold.js +22 -2
- package/dist/optimize/index.d.ts +9 -1
- package/dist/optimize/index.d.ts.map +1 -1
- package/dist/optimize/index.js +18 -3
- package/dist/optimize/map-node.d.ts +3 -1
- package/dist/optimize/map-node.d.ts.map +1 -1
- package/dist/optimize/map-node.js +45 -3
- package/dist/optimize/peephole.d.ts +16 -0
- package/dist/optimize/peephole.d.ts.map +1 -0
- package/dist/optimize/peephole.js +254 -0
- package/dist/optimize/remap.d.ts +2 -0
- package/dist/optimize/remap.d.ts.map +1 -1
- package/dist/optimize/remap.js +2 -0
- package/dist/optimize/rewrite.d.ts +13 -8
- package/dist/optimize/rewrite.d.ts.map +1 -1
- package/dist/optimize/rewrite.js +13 -8
- package/dist/plan/cache.d.ts +9 -3
- package/dist/plan/cache.d.ts.map +1 -1
- package/dist/plan/cache.js +21 -5
- package/dist/plan/index.d.ts +2 -0
- package/dist/plan/index.d.ts.map +1 -1
- package/dist/plan/index.js +2 -0
- package/dist/plan/predicate.d.ts +2 -0
- package/dist/plan/predicate.d.ts.map +1 -1
- package/dist/plan/predicate.js +268 -29
- package/dist/plan/schema-predicate.d.ts +6 -0
- package/dist/plan/schema-predicate.d.ts.map +1 -1
- package/dist/plan/schema-predicate.js +117 -13
- package/dist/plan/types.d.ts +2 -0
- package/dist/plan/types.d.ts.map +1 -1
- package/dist/plan/types.js +2 -0
- package/dist/result/index.d.ts +19 -5
- package/dist/result/index.d.ts.map +1 -1
- package/dist/result/index.js +10 -2
- package/dist/schema/common.d.ts +69 -6
- package/dist/schema/common.d.ts.map +1 -1
- package/dist/schema/common.js +104 -10
- package/dist/schema/freeze.d.ts +4 -0
- package/dist/schema/freeze.d.ts.map +1 -1
- package/dist/schema/freeze.js +18 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +3 -0
- package/dist/schema/lazy.d.ts +4 -0
- package/dist/schema/lazy.d.ts.map +1 -1
- package/dist/schema/lazy.js +4 -0
- package/dist/schema/literal.d.ts +7 -1
- package/dist/schema/literal.d.ts.map +1 -1
- package/dist/schema/literal.js +7 -1
- package/dist/schema/types.d.ts +20 -96
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +5 -1
- package/dist/schema/undefined.d.ts +17 -0
- package/dist/schema/undefined.d.ts.map +1 -0
- package/dist/schema/undefined.js +72 -0
- package/dist/schema/validate.d.ts +8 -1
- package/dist/schema/validate.d.ts.map +1 -1
- package/dist/schema/validate.js +146 -55
- package/docs/api.md +57 -0
- package/docs/assets/benchmark-headline.svg +163 -0
- package/docs/engine-notes.md +58 -15
- package/docs/index.html +130 -110
- package/package.json +65 -65
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file domain.ts
|
|
3
|
+
* @brief Validation-domain specialization for dispatch child graphs.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
6
|
+
*/
|
|
7
|
+
import { NodeTag } from "../kind/index.js";
|
|
8
|
+
import { compactReachable } from "./compact.js";
|
|
9
|
+
import { peepholeGraph } from "./peephole.js";
|
|
10
|
+
import { foldConstants } from "./fold.js";
|
|
11
|
+
import { ensureConst, keep, replace } from "./fold-common.js";
|
|
12
|
+
import { resolveAlias, rewriteNodeDeps } from "./rewrite.js";
|
|
13
|
+
const DomainMask = {
|
|
14
|
+
String: 1 << 0,
|
|
15
|
+
Number: 1 << 1,
|
|
16
|
+
Boolean: 1 << 2,
|
|
17
|
+
BigInt: 1 << 3,
|
|
18
|
+
Symbol: 1 << 4,
|
|
19
|
+
Undefined: 1 << 5,
|
|
20
|
+
Null: 1 << 6,
|
|
21
|
+
Array: 1 << 7,
|
|
22
|
+
Object: 1 << 8,
|
|
23
|
+
Function: 1 << 9
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* @brief Specialize nested validation graphs with domain knowledge.
|
|
27
|
+
* @details Dispatch nodes already know the primitive domain of each child arm.
|
|
28
|
+
* This pass pushes that fact into child graphs so redundant type checks collapse.
|
|
29
|
+
* @param graph Root graph to specialize.
|
|
30
|
+
* @returns The original graph when no node changed, otherwise a rewritten graph.
|
|
31
|
+
*/
|
|
32
|
+
export function specializeDomains(graph) {
|
|
33
|
+
let changed = false;
|
|
34
|
+
const nodes = new Array(graph.nodes.length);
|
|
35
|
+
for (let index = 0; index < graph.nodes.length; index += 1) {
|
|
36
|
+
const node = graph.nodes[index];
|
|
37
|
+
if (node === undefined) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const specialized = specializeChildDomains(node, graph.nodes);
|
|
41
|
+
nodes[index] = specialized;
|
|
42
|
+
changed = changed || specialized !== node;
|
|
43
|
+
}
|
|
44
|
+
if (!changed) {
|
|
45
|
+
return graph;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
nodes,
|
|
49
|
+
entry: graph.entry,
|
|
50
|
+
result: graph.result
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* @brief Execute specialize child domains.
|
|
55
|
+
* @details Optimizer helpers preserve graph equivalence while reducing redundant validation work.
|
|
56
|
+
*/
|
|
57
|
+
function specializeChildDomains(node, nodes) {
|
|
58
|
+
switch (node.tag) {
|
|
59
|
+
case NodeTag.And:
|
|
60
|
+
return specializeIterationDomains(node, nodes);
|
|
61
|
+
case NodeTag.ArrayEvery: {
|
|
62
|
+
const itemGraph = specializeDomains(node.itemGraph);
|
|
63
|
+
if (itemGraph === node.itemGraph) {
|
|
64
|
+
return node;
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
...node,
|
|
68
|
+
itemGraph
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
case NodeTag.TupleItems: {
|
|
72
|
+
const itemGraphs = specializeGraphArray(node.itemGraphs);
|
|
73
|
+
if (itemGraphs === node.itemGraphs) {
|
|
74
|
+
return node;
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
...node,
|
|
78
|
+
itemGraphs
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
case NodeTag.RecordEvery: {
|
|
82
|
+
const itemGraph = specializeDomains(node.itemGraph);
|
|
83
|
+
if (itemGraph === node.itemGraph) {
|
|
84
|
+
return node;
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
...node,
|
|
88
|
+
itemGraph
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
case NodeTag.DiscriminantDispatch: {
|
|
92
|
+
const graphs = specializeGraphArray(node.graphs);
|
|
93
|
+
if (graphs === node.graphs) {
|
|
94
|
+
return node;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
...node,
|
|
98
|
+
graphs
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
case NodeTag.ObjectShape: {
|
|
102
|
+
const entries = specializeObjectShapeEntries(node.entries);
|
|
103
|
+
if (entries === node.entries) {
|
|
104
|
+
return node;
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
...node,
|
|
108
|
+
entries
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
case NodeTag.UnionDispatch: {
|
|
112
|
+
const graphs = specializeGraphsForMasks(node.graphs, node.masks);
|
|
113
|
+
if (graphs === node.graphs) {
|
|
114
|
+
return node;
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
...node,
|
|
118
|
+
graphs
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
case NodeTag.PrimitiveUnion: {
|
|
122
|
+
const graphs = specializeGraphsForMasks(node.graphs, node.masks);
|
|
123
|
+
if (graphs === node.graphs) {
|
|
124
|
+
return node;
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
...node,
|
|
128
|
+
graphs
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
default:
|
|
132
|
+
return node;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* @brief Remove container guards already proven by iteration nodes.
|
|
137
|
+
* @details `ArrayEvery(x)` implies `IsArray(x)` and `RecordEvery(x)` implies
|
|
138
|
+
* `IsObject(x)`. Removing the sibling guard keeps the IR closer to the code
|
|
139
|
+
* that will be emitted.
|
|
140
|
+
* @param node Boolean fold node whose operands may contain container domains.
|
|
141
|
+
* @param nodes Graph node table used to inspect operands.
|
|
142
|
+
* @returns Rewritten boolean node, or the original node when nothing changed.
|
|
143
|
+
*/
|
|
144
|
+
function specializeIterationDomains(node, nodes) {
|
|
145
|
+
const domains = collectIterationDomains(node.values, nodes);
|
|
146
|
+
if (domains.length === 0) {
|
|
147
|
+
return node;
|
|
148
|
+
}
|
|
149
|
+
let changed = false;
|
|
150
|
+
const values = [];
|
|
151
|
+
for (let index = 0; index < node.values.length; index += 1) {
|
|
152
|
+
const value = node.values[index];
|
|
153
|
+
if (value === undefined) {
|
|
154
|
+
changed = true;
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (isIterationDomainGuard(value, nodes, domains)) {
|
|
158
|
+
/*
|
|
159
|
+
* The iterator node performs the same container guard before it can
|
|
160
|
+
* enter its child graph, so keeping this sibling check is redundant.
|
|
161
|
+
*/
|
|
162
|
+
changed = true;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
values.push(value);
|
|
166
|
+
}
|
|
167
|
+
if (!changed) {
|
|
168
|
+
return node;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
id: node.id,
|
|
172
|
+
tag: node.tag,
|
|
173
|
+
deps: values,
|
|
174
|
+
values
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* @brief Collect domains implied by iteration nodes inside one boolean fold.
|
|
179
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
180
|
+
* before code generation consumes the graph.
|
|
181
|
+
* @param values Operand ids from an And/Or-like fold.
|
|
182
|
+
* @param nodes Graph node table used to inspect operands.
|
|
183
|
+
* @returns Iteration domains visible from the operand list.
|
|
184
|
+
*/
|
|
185
|
+
function collectIterationDomains(values, nodes) {
|
|
186
|
+
const domains = [];
|
|
187
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
188
|
+
const value = values[index];
|
|
189
|
+
if (value === undefined) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const node = nodes[value];
|
|
193
|
+
if (node === undefined) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const domain = readIterationDomain(node);
|
|
197
|
+
if (domain !== undefined) {
|
|
198
|
+
domains.push(domain);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return domains;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* @brief Test whether a boolean operand is redundant due to an iteration domain.
|
|
205
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
206
|
+
* before code generation consumes the graph.
|
|
207
|
+
* @param value Candidate guard node id.
|
|
208
|
+
* @param nodes Graph node table used to inspect the candidate.
|
|
209
|
+
* @param domains Domains collected from sibling iteration nodes.
|
|
210
|
+
* @returns True when the candidate guard repeats a sibling iterator guard.
|
|
211
|
+
*/
|
|
212
|
+
function isIterationDomainGuard(value, nodes, domains) {
|
|
213
|
+
const node = nodes[value];
|
|
214
|
+
if (node === undefined || !isContainerGuardNode(node)) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
for (let index = 0; index < domains.length; index += 1) {
|
|
218
|
+
const domain = domains[index];
|
|
219
|
+
if (domain?.guard === node.tag && domain.value === node.value) {
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* @brief Read the guard implied by an iteration node.
|
|
227
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
228
|
+
* before code generation consumes the graph.
|
|
229
|
+
* @param node Candidate graph node.
|
|
230
|
+
* @returns Array/Object guard implied by the node, or undefined.
|
|
231
|
+
*/
|
|
232
|
+
function readIterationDomain(node) {
|
|
233
|
+
switch (node.tag) {
|
|
234
|
+
case NodeTag.ArrayEvery:
|
|
235
|
+
case NodeTag.TupleItems:
|
|
236
|
+
return {
|
|
237
|
+
value: node.value,
|
|
238
|
+
guard: NodeTag.IsArray
|
|
239
|
+
};
|
|
240
|
+
case NodeTag.RecordEvery:
|
|
241
|
+
return {
|
|
242
|
+
value: node.value,
|
|
243
|
+
guard: NodeTag.IsObject
|
|
244
|
+
};
|
|
245
|
+
default:
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* @brief Test whether a node is a plain container guard over one value edge.
|
|
251
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
252
|
+
* before code generation consumes the graph.
|
|
253
|
+
* @param node Candidate graph node.
|
|
254
|
+
* @returns True for array/object guard nodes.
|
|
255
|
+
*/
|
|
256
|
+
function isContainerGuardNode(node) {
|
|
257
|
+
return node.tag === NodeTag.IsArray || node.tag === NodeTag.IsObject;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* @brief Recursively specialize every graph in a closed graph list.
|
|
261
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
262
|
+
* before code generation consumes the graph.
|
|
263
|
+
* @param graphs Child graph list.
|
|
264
|
+
* @returns Original list when no child changed, otherwise a rewritten list.
|
|
265
|
+
*/
|
|
266
|
+
function specializeGraphArray(graphs) {
|
|
267
|
+
let changed = false;
|
|
268
|
+
const specialized = new Array(graphs.length);
|
|
269
|
+
for (let index = 0; index < graphs.length; index += 1) {
|
|
270
|
+
const graph = graphs[index];
|
|
271
|
+
if (graph === undefined) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
const next = specializeDomains(graph);
|
|
275
|
+
specialized[index] = next;
|
|
276
|
+
changed = changed || next !== graph;
|
|
277
|
+
}
|
|
278
|
+
return changed ? specialized : graphs;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* @brief Specialize child graphs using the dispatch mask assigned to each arm.
|
|
282
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
283
|
+
* before code generation consumes the graph.
|
|
284
|
+
* @param graphs Child graph list.
|
|
285
|
+
* @param masks Primitive-domain mask per graph.
|
|
286
|
+
* @returns Original list when no child changed, otherwise a rewritten list.
|
|
287
|
+
*/
|
|
288
|
+
function specializeGraphsForMasks(graphs, masks) {
|
|
289
|
+
let changed = false;
|
|
290
|
+
const specialized = new Array(graphs.length);
|
|
291
|
+
for (let index = 0; index < graphs.length; index += 1) {
|
|
292
|
+
const graph = graphs[index];
|
|
293
|
+
const mask = masks[index];
|
|
294
|
+
if (graph === undefined || mask === undefined) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
/*
|
|
298
|
+
* Domain specialization can expose constants, so run the light cleanup
|
|
299
|
+
* stack immediately before the child graph is stored back.
|
|
300
|
+
*/
|
|
301
|
+
const child = optimizeGraphForMask(specializeDomains(graph), mask);
|
|
302
|
+
specialized[index] = child;
|
|
303
|
+
changed = changed || child !== graph;
|
|
304
|
+
}
|
|
305
|
+
return changed ? specialized : graphs;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* @brief Specialize object-shape entry graphs without touching entry metadata.
|
|
309
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
310
|
+
* before code generation consumes the graph.
|
|
311
|
+
* @param entries Object-shape entries.
|
|
312
|
+
* @returns Original entry list when no graph changed, otherwise a rewritten list.
|
|
313
|
+
*/
|
|
314
|
+
function specializeObjectShapeEntries(entries) {
|
|
315
|
+
let changed = false;
|
|
316
|
+
const specialized = new Array(entries.length);
|
|
317
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
318
|
+
const entry = entries[index];
|
|
319
|
+
if (entry === undefined) {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
const graph = specializeDomains(entry.graph);
|
|
323
|
+
if (graph === entry.graph) {
|
|
324
|
+
specialized[index] = entry;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
changed = true;
|
|
328
|
+
specialized[index] = {
|
|
329
|
+
key: entry.key,
|
|
330
|
+
schema: entry.schema,
|
|
331
|
+
graph,
|
|
332
|
+
presence: entry.presence
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
return changed ? specialized : entries;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* @brief Specialize and clean a graph for one known primitive-domain mask.
|
|
339
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
340
|
+
* before code generation consumes the graph.
|
|
341
|
+
* @param graph Child graph to specialize.
|
|
342
|
+
* @param mask Primitive-domain mask proven by the dispatch parent.
|
|
343
|
+
* @returns Optimized graph for the narrowed domain.
|
|
344
|
+
*/
|
|
345
|
+
function optimizeGraphForMask(graph, mask) {
|
|
346
|
+
const specialized = specializeGraphForMask(graph, mask);
|
|
347
|
+
if (specialized === graph) {
|
|
348
|
+
return graph;
|
|
349
|
+
}
|
|
350
|
+
return compactReachable(peepholeGraph(foldConstants(specialized)));
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* @brief Rewrite one graph under a known input-domain mask.
|
|
354
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
355
|
+
* before code generation consumes the graph.
|
|
356
|
+
* @param graph Graph whose root parameter has the supplied mask.
|
|
357
|
+
* @param mask Primitive-domain mask for the graph parameter.
|
|
358
|
+
* @returns Original graph when no node changed, otherwise a rewritten graph.
|
|
359
|
+
*/
|
|
360
|
+
function specializeGraphForMask(graph, mask) {
|
|
361
|
+
const originalLength = graph.nodes.length;
|
|
362
|
+
const nodes = graph.nodes.slice();
|
|
363
|
+
const aliases = new Array(nodes.length);
|
|
364
|
+
let changed = false;
|
|
365
|
+
for (let index = 0; index < aliases.length; index += 1) {
|
|
366
|
+
aliases[index] = index;
|
|
367
|
+
}
|
|
368
|
+
for (let index = 0; index < originalLength; index += 1) {
|
|
369
|
+
const node = nodes[index];
|
|
370
|
+
if (node === undefined) {
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
const rewritten = rewriteNodeDeps(node, aliases);
|
|
374
|
+
const result = specializeNodeForMask(rewritten, nodes, aliases, mask);
|
|
375
|
+
nodes[index] = result.node;
|
|
376
|
+
if (result.replacement !== undefined) {
|
|
377
|
+
/*
|
|
378
|
+
* Replacements are recorded as aliases first. A final rewrite pass
|
|
379
|
+
* then updates every dependency after the alias forest has settled.
|
|
380
|
+
*/
|
|
381
|
+
aliases[index] = result.replacement;
|
|
382
|
+
changed = true;
|
|
383
|
+
}
|
|
384
|
+
changed = changed || result.node !== rewritten;
|
|
385
|
+
}
|
|
386
|
+
if (!changed) {
|
|
387
|
+
return graph;
|
|
388
|
+
}
|
|
389
|
+
for (let index = 0; index < aliases.length; index += 1) {
|
|
390
|
+
aliases[index] = resolveAlias(index, aliases);
|
|
391
|
+
}
|
|
392
|
+
const rewritten = new Array(nodes.length);
|
|
393
|
+
for (let index = 0; index < nodes.length; index += 1) {
|
|
394
|
+
const node = nodes[index];
|
|
395
|
+
if (node !== undefined) {
|
|
396
|
+
rewritten[index] = rewriteNodeDeps(node, aliases);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
nodes: rewritten,
|
|
401
|
+
entry: resolveAlias(graph.entry, aliases),
|
|
402
|
+
result: resolveAlias(graph.result, aliases)
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* @brief Specialize a single graph node against a primitive-domain mask.
|
|
407
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
408
|
+
* before code generation consumes the graph.
|
|
409
|
+
* @param node Node with dependencies already rewritten through current aliases.
|
|
410
|
+
* @param nodes Mutable graph node table used for constants.
|
|
411
|
+
* @param aliases Alias table updated by replacement folds.
|
|
412
|
+
* @param mask Primitive-domain mask proven for the root parameter.
|
|
413
|
+
* @returns Fold decision for the node.
|
|
414
|
+
*/
|
|
415
|
+
function specializeNodeForMask(node, nodes, aliases, mask) {
|
|
416
|
+
switch (node.tag) {
|
|
417
|
+
case NodeTag.IsString:
|
|
418
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.String);
|
|
419
|
+
case NodeTag.IsBoolean:
|
|
420
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.Boolean);
|
|
421
|
+
case NodeTag.IsBigInt:
|
|
422
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.BigInt);
|
|
423
|
+
case NodeTag.IsSymbol:
|
|
424
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.Symbol);
|
|
425
|
+
case NodeTag.IsUndefined:
|
|
426
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.Undefined);
|
|
427
|
+
case NodeTag.IsNull:
|
|
428
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.Null);
|
|
429
|
+
case NodeTag.IsArray:
|
|
430
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.Array);
|
|
431
|
+
case NodeTag.IsObject:
|
|
432
|
+
return specializeUnaryType(node, nodes, aliases, mask, DomainMask.Object);
|
|
433
|
+
case NodeTag.IsNumber:
|
|
434
|
+
case NodeTag.IsInteger:
|
|
435
|
+
return specializeNumericType(node, nodes, aliases, mask);
|
|
436
|
+
case NodeTag.StringMin:
|
|
437
|
+
case NodeTag.StringMax:
|
|
438
|
+
case NodeTag.Regex:
|
|
439
|
+
return specializeStringDomain(node, nodes, aliases, mask);
|
|
440
|
+
case NodeTag.Gte:
|
|
441
|
+
case NodeTag.Lte:
|
|
442
|
+
return specializeNumericDomain(node, nodes, aliases, mask);
|
|
443
|
+
case NodeTag.Equals:
|
|
444
|
+
return specializeEqualityDomain(node, nodes, aliases, mask);
|
|
445
|
+
case NodeTag.ArrayEvery:
|
|
446
|
+
case NodeTag.TupleItems:
|
|
447
|
+
return specializeValueDomain(node, nodes, aliases, mask, DomainMask.Array);
|
|
448
|
+
case NodeTag.RecordEvery:
|
|
449
|
+
case NodeTag.ObjectShape:
|
|
450
|
+
case NodeTag.DiscriminantDispatch:
|
|
451
|
+
case NodeTag.StrictKeys:
|
|
452
|
+
return specializeValueDomain(node, nodes, aliases, mask, DomainMask.Object);
|
|
453
|
+
default:
|
|
454
|
+
return keep(node);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* @brief Specialize a unary type guard.
|
|
459
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
460
|
+
* before code generation consumes the graph.
|
|
461
|
+
* @param node Guard node whose value edge may point at the root parameter.
|
|
462
|
+
* @param nodes Mutable graph node table used for constants.
|
|
463
|
+
* @param aliases Alias table updated by replacement folds.
|
|
464
|
+
* @param mask Primitive-domain mask proven for the root parameter.
|
|
465
|
+
* @param bit Domain bit represented by the guard.
|
|
466
|
+
* @returns Constant true/false when the mask proves the answer, otherwise keep.
|
|
467
|
+
*/
|
|
468
|
+
function specializeUnaryType(node, nodes, aliases, mask, bit) {
|
|
469
|
+
if (!isParamNode(nodes, node.value)) {
|
|
470
|
+
return keep(node);
|
|
471
|
+
}
|
|
472
|
+
if ((mask & bit) === 0) {
|
|
473
|
+
/*
|
|
474
|
+
* The parent dispatch has excluded this type, so the guard is statically
|
|
475
|
+
* false inside this arm.
|
|
476
|
+
*/
|
|
477
|
+
return replace(node, ensureConst(nodes, aliases, false));
|
|
478
|
+
}
|
|
479
|
+
if (mask === bit) {
|
|
480
|
+
/*
|
|
481
|
+
* The arm contains only this type, so the guard is statically true and
|
|
482
|
+
* later boolean folding can remove it.
|
|
483
|
+
*/
|
|
484
|
+
return replace(node, ensureConst(nodes, aliases, true));
|
|
485
|
+
}
|
|
486
|
+
return keep(node);
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* @brief Specialize number and integer guards.
|
|
490
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
491
|
+
* before code generation consumes the graph.
|
|
492
|
+
* @param node Numeric guard node.
|
|
493
|
+
* @param nodes Mutable graph node table used for constants.
|
|
494
|
+
* @param aliases Alias table updated by replacement folds.
|
|
495
|
+
* @param mask Primitive-domain mask proven for the root parameter.
|
|
496
|
+
* @returns Constant false when number is excluded, otherwise keep.
|
|
497
|
+
*/
|
|
498
|
+
function specializeNumericType(node, nodes, aliases, mask) {
|
|
499
|
+
if (isParamNode(nodes, node.value) && (mask & DomainMask.Number) === 0) {
|
|
500
|
+
return replace(node, ensureConst(nodes, aliases, false));
|
|
501
|
+
}
|
|
502
|
+
return keep(node);
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* @brief Specialize string-only scalar checks.
|
|
506
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
507
|
+
* before code generation consumes the graph.
|
|
508
|
+
* @param node String check node.
|
|
509
|
+
* @param nodes Mutable graph node table used for constants.
|
|
510
|
+
* @param aliases Alias table updated by replacement folds.
|
|
511
|
+
* @param mask Primitive-domain mask proven for the root parameter.
|
|
512
|
+
* @returns Constant false when string is excluded, otherwise keep.
|
|
513
|
+
*/
|
|
514
|
+
function specializeStringDomain(node, nodes, aliases, mask) {
|
|
515
|
+
if (isParamNode(nodes, node.value) && (mask & DomainMask.String) === 0) {
|
|
516
|
+
return replace(node, ensureConst(nodes, aliases, false));
|
|
517
|
+
}
|
|
518
|
+
return keep(node);
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* @brief Specialize numeric bound checks.
|
|
522
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
523
|
+
* before code generation consumes the graph.
|
|
524
|
+
* @param node Numeric bound node.
|
|
525
|
+
* @param nodes Mutable graph node table used for constants.
|
|
526
|
+
* @param aliases Alias table updated by replacement folds.
|
|
527
|
+
* @param mask Primitive-domain mask proven for the root parameter.
|
|
528
|
+
* @returns Constant false when number is excluded, otherwise keep.
|
|
529
|
+
*/
|
|
530
|
+
function specializeNumericDomain(node, nodes, aliases, mask) {
|
|
531
|
+
if (isParamNode(nodes, node.left) && (mask & DomainMask.Number) === 0) {
|
|
532
|
+
return replace(node, ensureConst(nodes, aliases, false));
|
|
533
|
+
}
|
|
534
|
+
return keep(node);
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* @brief Specialize equality checks against a known primitive domain.
|
|
538
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
539
|
+
* before code generation consumes the graph.
|
|
540
|
+
* @param node Equality node.
|
|
541
|
+
* @param nodes Mutable graph node table used for constants.
|
|
542
|
+
* @param aliases Alias table updated by replacement folds.
|
|
543
|
+
* @param mask Primitive-domain mask proven for the root parameter.
|
|
544
|
+
* @returns Constant false when the literal cannot belong to the domain.
|
|
545
|
+
*/
|
|
546
|
+
function specializeEqualityDomain(node, nodes, aliases, mask) {
|
|
547
|
+
const left = nodes[node.left];
|
|
548
|
+
const right = nodes[node.right];
|
|
549
|
+
if (left?.tag === NodeTag.Param && right?.tag === NodeTag.Const &&
|
|
550
|
+
(mask & literalMask(right.value)) === 0) {
|
|
551
|
+
return replace(node, ensureConst(nodes, aliases, false));
|
|
552
|
+
}
|
|
553
|
+
if (right?.tag === NodeTag.Param && left?.tag === NodeTag.Const &&
|
|
554
|
+
(mask & literalMask(left.value)) === 0) {
|
|
555
|
+
return replace(node, ensureConst(nodes, aliases, false));
|
|
556
|
+
}
|
|
557
|
+
return keep(node);
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* @brief Specialize container-value nodes against a known primitive domain.
|
|
561
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
562
|
+
* before code generation consumes the graph.
|
|
563
|
+
* @param node Node that may carry a `value` edge.
|
|
564
|
+
* @param nodes Mutable graph node table used for constants.
|
|
565
|
+
* @param aliases Alias table updated by replacement folds.
|
|
566
|
+
* @param mask Primitive-domain mask proven for the root parameter.
|
|
567
|
+
* @param bit Container domain bit required by the node.
|
|
568
|
+
* @returns Constant false when the container type is excluded, otherwise keep.
|
|
569
|
+
*/
|
|
570
|
+
function specializeValueDomain(node, nodes, aliases, mask, bit) {
|
|
571
|
+
if (!("value" in node) || typeof node.value !== "number") {
|
|
572
|
+
return keep(node);
|
|
573
|
+
}
|
|
574
|
+
if (isParamNode(nodes, node.value) && (mask & bit) === 0) {
|
|
575
|
+
return replace(node, ensureConst(nodes, aliases, false));
|
|
576
|
+
}
|
|
577
|
+
return keep(node);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* @brief Test whether a node id names the root graph parameter.
|
|
581
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
582
|
+
* before code generation consumes the graph.
|
|
583
|
+
* @param nodes Graph node table.
|
|
584
|
+
* @param id Candidate node id.
|
|
585
|
+
* @returns True when the id points at a Param node.
|
|
586
|
+
*/
|
|
587
|
+
function isParamNode(nodes, id) {
|
|
588
|
+
return nodes[id]?.tag === NodeTag.Param;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* @brief Convert a literal value into its primitive-domain mask bit.
|
|
592
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
593
|
+
* before code generation consumes the graph.
|
|
594
|
+
* @param value Literal value carried by an Equals node.
|
|
595
|
+
* @returns Domain mask bit for the literal's runtime type.
|
|
596
|
+
*/
|
|
597
|
+
function literalMask(value) {
|
|
598
|
+
if (value === null) {
|
|
599
|
+
return DomainMask.Null;
|
|
600
|
+
}
|
|
601
|
+
switch (typeof value) {
|
|
602
|
+
case "string":
|
|
603
|
+
return DomainMask.String;
|
|
604
|
+
case "number":
|
|
605
|
+
return DomainMask.Number;
|
|
606
|
+
case "boolean":
|
|
607
|
+
return DomainMask.Boolean;
|
|
608
|
+
case "bigint":
|
|
609
|
+
return DomainMask.BigInt;
|
|
610
|
+
case "symbol":
|
|
611
|
+
return DomainMask.Symbol;
|
|
612
|
+
case "undefined":
|
|
613
|
+
return DomainMask.Undefined;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file fold-boolean.ts
|
|
3
3
|
* @brief Constant folding for boolean fold nodes.
|
|
4
|
+
* @details Optimizer helpers preserve graph equivalence while shrinking redundant nodes
|
|
5
|
+
* before code generation consumes the graph.
|
|
4
6
|
*/
|
|
5
7
|
import type { BooleanFoldNode, GraphNode, NodeId } from "../ir/index.js";
|
|
6
8
|
import { type FoldResult } from "./fold-common.js";
|
|
7
9
|
/**
|
|
8
|
-
* @brief fold and.
|
|
10
|
+
* @brief Simplify an `And` fold node using boolean identities and constraints.
|
|
11
|
+
* @details False annihilates the whole conjunction, true disappears, nested
|
|
12
|
+
* conjunctions are flattened, and scalar constraints are canonicalized after
|
|
13
|
+
* algebraic simplification.
|
|
14
|
+
* @param node Boolean fold node to simplify.
|
|
15
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
16
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
17
|
+
* @returns Fold result for the conjunction.
|
|
9
18
|
*/
|
|
10
19
|
export declare function foldAnd(node: BooleanFoldNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
11
20
|
/**
|
|
12
|
-
* @brief fold
|
|
21
|
+
* @brief Simplify an `Or` fold node using boolean identities and tautologies.
|
|
22
|
+
* @details True satisfies the whole disjunction, false disappears, nested
|
|
23
|
+
* disjunctions are flattened, and duplicate surviving arms are removed.
|
|
24
|
+
* @param node Boolean fold node to simplify.
|
|
25
|
+
* @param nodes Mutable graph node table for constant interning.
|
|
26
|
+
* @param aliases Mutable alias table updated when a constant is inserted.
|
|
27
|
+
* @returns Fold result for the disjunction.
|
|
13
28
|
*/
|
|
14
29
|
export declare function foldOr(node: BooleanFoldNode, nodes: GraphNode[], aliases: NodeId[]): FoldResult;
|
|
15
30
|
//# sourceMappingURL=fold-boolean.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fold-boolean.d.ts","sourceRoot":"","sources":["../../src/optimize/fold-boolean.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fold-boolean.d.ts","sourceRoot":"","sources":["../../src/optimize/fold-boolean.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACR,eAAe,EACf,SAAS,EACT,MAAM,EACT,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAKH,KAAK,UAAU,EAClB,MAAM,kBAAkB,CAAC;AAW1B;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CACnB,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CA+CZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAClB,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,SAAS,EAAE,EAClB,OAAO,EAAE,MAAM,EAAE,GAClB,UAAU,CA2CZ"}
|