@markw65/monkeyc-optimizer 1.0.29 → 1.0.30
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/README.md +13 -0
- package/build/api.cjs +66 -28
- package/build/optimizer.cjs +67 -29
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -330,3 +330,16 @@ More fixes found via open source projects.
|
|
|
330
330
|
- Actually run the rest of the expected-to-crash tests
|
|
331
331
|
- Better error messages from pragma checker
|
|
332
332
|
- Better regex for filtering projects
|
|
333
|
+
|
|
334
|
+
### 1.0.30
|
|
335
|
+
|
|
336
|
+
- Less greedy approach to finding candidate sets
|
|
337
|
+
- slightly better size reduction when globals maybe modified
|
|
338
|
+
- Fix the control flow after the test of a while loop
|
|
339
|
+
- one of the edges was in the wrong place, leading to suboptimal solutions in some cases
|
|
340
|
+
|
|
341
|
+
Bug Fixes
|
|
342
|
+
|
|
343
|
+
- Fix a bug that could lead to the optimizer never completing
|
|
344
|
+
- Fix a bug that prevented inlining functions that ended in a BlockStatement
|
|
345
|
+
- Fix a bug that could cause nested inlined functions inlined in declarations to not be removed
|
package/build/api.cjs
CHANGED
|
@@ -928,6 +928,10 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
928
928
|
if (!func.node || !func.node.body) {
|
|
929
929
|
return null;
|
|
930
930
|
}
|
|
931
|
+
const lastStmt = (block) => {
|
|
932
|
+
const last = block.body.slice(-1)[0];
|
|
933
|
+
return last.type === "BlockStatement" ? lastStmt(last) : [last, block];
|
|
934
|
+
};
|
|
931
935
|
let retStmtCount = 0;
|
|
932
936
|
if (context.type === "ReturnStatement") {
|
|
933
937
|
const last = func.node.body.body.slice(-1)[0];
|
|
@@ -950,7 +954,7 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
950
954
|
return null;
|
|
951
955
|
}
|
|
952
956
|
if (retStmtCount === 1) {
|
|
953
|
-
const last = func.node.body
|
|
957
|
+
const [last] = lastStmt(func.node.body);
|
|
954
958
|
if (!last ||
|
|
955
959
|
last.type !== "ReturnStatement" ||
|
|
956
960
|
((context.type === "AssignmentExpression" ||
|
|
@@ -975,21 +979,21 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
975
979
|
}
|
|
976
980
|
inliner_diagnostic(state, call.loc, null);
|
|
977
981
|
if (context.type !== "ReturnStatement" && retStmtCount) {
|
|
978
|
-
const last = body
|
|
982
|
+
const [last, block] = lastStmt(body);
|
|
979
983
|
if (last.type != "ReturnStatement") {
|
|
980
984
|
throw new Error("ReturnStatement got lost!");
|
|
981
985
|
}
|
|
982
986
|
if (last.argument) {
|
|
983
987
|
if (context.type === "AssignmentExpression") {
|
|
984
988
|
context.right = last.argument;
|
|
985
|
-
|
|
989
|
+
block.body[block.body.length - 1] = {
|
|
986
990
|
type: "ExpressionStatement",
|
|
987
991
|
expression: context,
|
|
988
992
|
};
|
|
989
993
|
}
|
|
990
994
|
else if (context.type === "VariableDeclarator") {
|
|
991
995
|
const { id, init: _init, kind: _kind, ...rest } = context;
|
|
992
|
-
|
|
996
|
+
block.body[block.body.length - 1] = {
|
|
993
997
|
...rest,
|
|
994
998
|
type: "ExpressionStatement",
|
|
995
999
|
expression: {
|
|
@@ -1003,11 +1007,11 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
1003
1007
|
}
|
|
1004
1008
|
else {
|
|
1005
1009
|
const side_exprs = inliner_unused(last.argument);
|
|
1006
|
-
|
|
1010
|
+
block.body.splice(block.body.length - 1, 1, ...side_exprs);
|
|
1007
1011
|
}
|
|
1008
1012
|
}
|
|
1009
1013
|
else {
|
|
1010
|
-
--
|
|
1014
|
+
--block.body.length;
|
|
1011
1015
|
}
|
|
1012
1016
|
}
|
|
1013
1017
|
return body;
|
|
@@ -1271,7 +1275,8 @@ function control_flow_buildReducedGraph(state, func, notice) {
|
|
|
1271
1275
|
if (node.type === "WhileStatement") {
|
|
1272
1276
|
head = localState.newBlock(top.continue);
|
|
1273
1277
|
state.traverse(node.test);
|
|
1274
|
-
localState.addEdge(localState.
|
|
1278
|
+
localState.addEdge(localState.curBlock, top.break);
|
|
1279
|
+
localState.newBlock();
|
|
1275
1280
|
}
|
|
1276
1281
|
else {
|
|
1277
1282
|
head = localState.newBlock();
|
|
@@ -1592,6 +1597,8 @@ function cleanCfg(head) {
|
|
|
1592
1597
|
}
|
|
1593
1598
|
}));
|
|
1594
1599
|
}
|
|
1600
|
+
if (!cur.node)
|
|
1601
|
+
cur.node = succ.node;
|
|
1595
1602
|
}
|
|
1596
1603
|
}
|
|
1597
1604
|
});
|
|
@@ -1690,6 +1697,20 @@ function declName(decl) {
|
|
|
1690
1697
|
throw new Error(`Unexpected EventDecl type: ${decl.type}`);
|
|
1691
1698
|
}
|
|
1692
1699
|
}
|
|
1700
|
+
function logAntState(s, decl) {
|
|
1701
|
+
const defs = Array.from(s.ant).reduce((defs, event) => {
|
|
1702
|
+
if (event.type === "def" || event.type === "mod")
|
|
1703
|
+
defs++;
|
|
1704
|
+
return defs;
|
|
1705
|
+
}, 0);
|
|
1706
|
+
console.log(` - ${declFullName(decl)}: ${candidateCost(s)} bytes, ${s.ant.size - defs} refs, ${defs} defs, ${s.live ? "" : "!"}live, ${s.isIsolated ? "" : "!"}isolated`);
|
|
1707
|
+
console.log(` - members: ${Array.from(s.members)
|
|
1708
|
+
.map(([block, live]) => block.order + (live ? "t" : "f"))
|
|
1709
|
+
.join(", ")}`);
|
|
1710
|
+
}
|
|
1711
|
+
function logAntDecls(antDecls) {
|
|
1712
|
+
antDecls.forEach(logAntState);
|
|
1713
|
+
}
|
|
1693
1714
|
function pre_sizeBasedPRE(state, func) {
|
|
1694
1715
|
if (!func.node.body)
|
|
1695
1716
|
return;
|
|
@@ -1704,14 +1725,7 @@ function pre_sizeBasedPRE(state, func) {
|
|
|
1704
1725
|
if (candidates) {
|
|
1705
1726
|
if (logging) {
|
|
1706
1727
|
console.log(`Found ${candidates.size} candidates in ${func.fullName}`);
|
|
1707
|
-
candidates
|
|
1708
|
-
const defs = Array.from(s.ant).reduce((defs, event) => {
|
|
1709
|
-
if (event.type === "def")
|
|
1710
|
-
defs++;
|
|
1711
|
-
return defs;
|
|
1712
|
-
}, 0);
|
|
1713
|
-
console.log(` - ${declFullName(decl)}: ${candidateCost(s)} bytes, ${s.ant.size - defs} refs, ${defs} defs, ${s.live ? "" : "!"}live`);
|
|
1714
|
-
});
|
|
1728
|
+
logAntDecls(candidates);
|
|
1715
1729
|
}
|
|
1716
1730
|
const nodeMap = new Map();
|
|
1717
1731
|
const declMap = new Map();
|
|
@@ -1957,21 +1971,28 @@ function cloneAnticipatedState(as) {
|
|
|
1957
1971
|
members: new Map(as.members),
|
|
1958
1972
|
};
|
|
1959
1973
|
}
|
|
1974
|
+
function mergeAnticipatedState(ae, be) {
|
|
1975
|
+
mergeSet(ae.ant, be.ant);
|
|
1976
|
+
be.members.forEach((live, block) => ae.members.set(block, live));
|
|
1977
|
+
if (be.live)
|
|
1978
|
+
ae.live = true;
|
|
1979
|
+
}
|
|
1960
1980
|
function cloneAnticipatedDecls(ad) {
|
|
1961
1981
|
const copy = anticipatedDecls();
|
|
1962
1982
|
for (const [k, v] of ad) {
|
|
1963
|
-
|
|
1983
|
+
if (!v.isIsolated) {
|
|
1984
|
+
copy.set(k, cloneAnticipatedState(v));
|
|
1985
|
+
}
|
|
1964
1986
|
}
|
|
1965
1987
|
return copy;
|
|
1966
1988
|
}
|
|
1967
1989
|
function mergeAnticipatedDecls(a, b) {
|
|
1968
1990
|
for (const [k, v] of b) {
|
|
1991
|
+
if (v.isIsolated)
|
|
1992
|
+
continue;
|
|
1969
1993
|
const ae = a.get(k);
|
|
1970
1994
|
if (ae) {
|
|
1971
|
-
|
|
1972
|
-
v.members.forEach((live, block) => ae.members.set(block, live));
|
|
1973
|
-
if (v.live)
|
|
1974
|
-
ae.live = true;
|
|
1995
|
+
mergeAnticipatedState(ae, v);
|
|
1975
1996
|
}
|
|
1976
1997
|
else {
|
|
1977
1998
|
a.set(k, cloneAnticipatedState(v));
|
|
@@ -1985,6 +2006,7 @@ function equalStates(a, b) {
|
|
|
1985
2006
|
const be = b.get(k);
|
|
1986
2007
|
if (!be ||
|
|
1987
2008
|
be.live != ae.live ||
|
|
2009
|
+
be.isIsolated != ae.isIsolated ||
|
|
1988
2010
|
!equalSet(ae.ant, be.ant) ||
|
|
1989
2011
|
!equalMap(ae.members, be.members)) {
|
|
1990
2012
|
return false;
|
|
@@ -2055,7 +2077,8 @@ function candidateCost(candState) {
|
|
|
2055
2077
|
cost += defCost(candState.node);
|
|
2056
2078
|
}
|
|
2057
2079
|
});
|
|
2058
|
-
|
|
2080
|
+
const boundarySize = candidateBoundary(candState).size;
|
|
2081
|
+
cost += defCost(candState.node) * boundarySize;
|
|
2059
2082
|
return cost;
|
|
2060
2083
|
}
|
|
2061
2084
|
function computeAttributes(head) {
|
|
@@ -2193,9 +2216,7 @@ function computeAttributes(head) {
|
|
|
2193
2216
|
if (isUpdate || candidates.live) {
|
|
2194
2217
|
candidates.ant.add(event);
|
|
2195
2218
|
}
|
|
2196
|
-
|
|
2197
|
-
candidates.live = false;
|
|
2198
|
-
}
|
|
2219
|
+
candidates.live = isUpdate;
|
|
2199
2220
|
break;
|
|
2200
2221
|
}
|
|
2201
2222
|
}
|
|
@@ -2204,12 +2225,23 @@ function computeAttributes(head) {
|
|
|
2204
2225
|
curState.forEach((antState) => {
|
|
2205
2226
|
antState.head = top;
|
|
2206
2227
|
antState.members.set(top, antState.live);
|
|
2228
|
+
if (!antState.live && candidateBoundary(antState).size === 0) {
|
|
2229
|
+
// we found a group that's isolated from the rest
|
|
2230
|
+
// of the function. Don't merge it with earlier
|
|
2231
|
+
// refs and defs, because we can take it or leave
|
|
2232
|
+
// it based on its own cost.
|
|
2233
|
+
antState.isIsolated = true;
|
|
2234
|
+
}
|
|
2207
2235
|
});
|
|
2208
2236
|
const oldState = blockStates[top.order];
|
|
2209
2237
|
if (oldState && equalStates(oldState, curState)) {
|
|
2210
2238
|
continue;
|
|
2211
2239
|
}
|
|
2212
2240
|
blockStates[top.order] = curState;
|
|
2241
|
+
if (logging) {
|
|
2242
|
+
console.log(`Updated block ${top.order}`);
|
|
2243
|
+
logAntDecls(curState);
|
|
2244
|
+
}
|
|
2213
2245
|
if (top.preds) {
|
|
2214
2246
|
top.preds.forEach((pred) => enqueue(pred));
|
|
2215
2247
|
}
|
|
@@ -2222,7 +2254,9 @@ function computeAttributes(head) {
|
|
|
2222
2254
|
if (cost >= 0)
|
|
2223
2255
|
return;
|
|
2224
2256
|
const existing = candidateDecls.get(decl);
|
|
2225
|
-
if (!existing ||
|
|
2257
|
+
if (!existing ||
|
|
2258
|
+
existing.isIsolated ||
|
|
2259
|
+
candidateCost(existing) > cost) {
|
|
2226
2260
|
const boundary = candidateBoundary(events);
|
|
2227
2261
|
if (!Array.from(boundary).every((block) => {
|
|
2228
2262
|
if (block !== events.head && block.events) {
|
|
@@ -2262,7 +2296,11 @@ function computeAttributes(head) {
|
|
|
2262
2296
|
return;
|
|
2263
2297
|
}
|
|
2264
2298
|
events.live = false;
|
|
2265
|
-
if (
|
|
2299
|
+
if (existing && existing.isIsolated) {
|
|
2300
|
+
delete existing.isIsolated;
|
|
2301
|
+
mergeAnticipatedState(events, existing);
|
|
2302
|
+
}
|
|
2303
|
+
else if (candidateCost(events) != cost) {
|
|
2266
2304
|
throw new Error(`cost of block ${i} changed`);
|
|
2267
2305
|
}
|
|
2268
2306
|
candidateDecls.set(decl, events);
|
|
@@ -3444,10 +3482,10 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
3444
3482
|
while (i < node.declarations.length) {
|
|
3445
3483
|
const decl = declarations[i++];
|
|
3446
3484
|
if (decl.init && decl.init.type === "CallExpression") {
|
|
3447
|
-
const inlined = optimizeCall(state, decl.init, decl);
|
|
3485
|
+
const inlined = replace(optimizeCall(state, decl.init, decl), decl.init);
|
|
3448
3486
|
if (!inlined)
|
|
3449
3487
|
continue;
|
|
3450
|
-
if (inlined.type != "BlockStatement") {
|
|
3488
|
+
if (Array.isArray(inlined) || inlined.type != "BlockStatement") {
|
|
3451
3489
|
throw new Error("Unexpected inlined result");
|
|
3452
3490
|
}
|
|
3453
3491
|
if (!results) {
|
package/build/optimizer.cjs
CHANGED
|
@@ -11625,6 +11625,10 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11625
11625
|
if (!func.node || !func.node.body) {
|
|
11626
11626
|
return null;
|
|
11627
11627
|
}
|
|
11628
|
+
const lastStmt = (block) => {
|
|
11629
|
+
const last = block.body.slice(-1)[0];
|
|
11630
|
+
return last.type === "BlockStatement" ? lastStmt(last) : [last, block];
|
|
11631
|
+
};
|
|
11628
11632
|
let retStmtCount = 0;
|
|
11629
11633
|
if (context.type === "ReturnStatement") {
|
|
11630
11634
|
const last = func.node.body.body.slice(-1)[0];
|
|
@@ -11647,7 +11651,7 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11647
11651
|
return null;
|
|
11648
11652
|
}
|
|
11649
11653
|
if (retStmtCount === 1) {
|
|
11650
|
-
const last = func.node.body
|
|
11654
|
+
const [last] = lastStmt(func.node.body);
|
|
11651
11655
|
if (!last ||
|
|
11652
11656
|
last.type !== "ReturnStatement" ||
|
|
11653
11657
|
((context.type === "AssignmentExpression" ||
|
|
@@ -11672,21 +11676,21 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11672
11676
|
}
|
|
11673
11677
|
diagnostic(state, call.loc, null);
|
|
11674
11678
|
if (context.type !== "ReturnStatement" && retStmtCount) {
|
|
11675
|
-
const last = body
|
|
11679
|
+
const [last, block] = lastStmt(body);
|
|
11676
11680
|
if (last.type != "ReturnStatement") {
|
|
11677
11681
|
throw new Error("ReturnStatement got lost!");
|
|
11678
11682
|
}
|
|
11679
11683
|
if (last.argument) {
|
|
11680
11684
|
if (context.type === "AssignmentExpression") {
|
|
11681
11685
|
context.right = last.argument;
|
|
11682
|
-
|
|
11686
|
+
block.body[block.body.length - 1] = {
|
|
11683
11687
|
type: "ExpressionStatement",
|
|
11684
11688
|
expression: context,
|
|
11685
11689
|
};
|
|
11686
11690
|
}
|
|
11687
11691
|
else if (context.type === "VariableDeclarator") {
|
|
11688
11692
|
const { id, init: _init, kind: _kind, ...rest } = context;
|
|
11689
|
-
|
|
11693
|
+
block.body[block.body.length - 1] = {
|
|
11690
11694
|
...rest,
|
|
11691
11695
|
type: "ExpressionStatement",
|
|
11692
11696
|
expression: {
|
|
@@ -11700,11 +11704,11 @@ function inlineWithArgs(state, func, call, context) {
|
|
|
11700
11704
|
}
|
|
11701
11705
|
else {
|
|
11702
11706
|
const side_exprs = unused(last.argument);
|
|
11703
|
-
|
|
11707
|
+
block.body.splice(block.body.length - 1, 1, ...side_exprs);
|
|
11704
11708
|
}
|
|
11705
11709
|
}
|
|
11706
11710
|
else {
|
|
11707
|
-
--
|
|
11711
|
+
--block.body.length;
|
|
11708
11712
|
}
|
|
11709
11713
|
}
|
|
11710
11714
|
return body;
|
|
@@ -11966,7 +11970,8 @@ function buildReducedGraph(state, func, notice) {
|
|
|
11966
11970
|
if (node.type === "WhileStatement") {
|
|
11967
11971
|
head = localState.newBlock(top.continue);
|
|
11968
11972
|
state.traverse(node.test);
|
|
11969
|
-
localState.addEdge(localState.
|
|
11973
|
+
localState.addEdge(localState.curBlock, top.break);
|
|
11974
|
+
localState.newBlock();
|
|
11970
11975
|
}
|
|
11971
11976
|
else {
|
|
11972
11977
|
head = localState.newBlock();
|
|
@@ -12287,6 +12292,8 @@ function cleanCfg(head) {
|
|
|
12287
12292
|
}
|
|
12288
12293
|
}));
|
|
12289
12294
|
}
|
|
12295
|
+
if (!cur.node)
|
|
12296
|
+
cur.node = succ.node;
|
|
12290
12297
|
}
|
|
12291
12298
|
}
|
|
12292
12299
|
});
|
|
@@ -12385,6 +12392,20 @@ function declName(decl) {
|
|
|
12385
12392
|
throw new Error(`Unexpected EventDecl type: ${decl.type}`);
|
|
12386
12393
|
}
|
|
12387
12394
|
}
|
|
12395
|
+
function logAntState(s, decl) {
|
|
12396
|
+
const defs = Array.from(s.ant).reduce((defs, event) => {
|
|
12397
|
+
if (event.type === "def" || event.type === "mod")
|
|
12398
|
+
defs++;
|
|
12399
|
+
return defs;
|
|
12400
|
+
}, 0);
|
|
12401
|
+
console.log(` - ${declFullName(decl)}: ${candidateCost(s)} bytes, ${s.ant.size - defs} refs, ${defs} defs, ${s.live ? "" : "!"}live, ${s.isIsolated ? "" : "!"}isolated`);
|
|
12402
|
+
console.log(` - members: ${Array.from(s.members)
|
|
12403
|
+
.map(([block, live]) => block.order + (live ? "t" : "f"))
|
|
12404
|
+
.join(", ")}`);
|
|
12405
|
+
}
|
|
12406
|
+
function logAntDecls(antDecls) {
|
|
12407
|
+
antDecls.forEach(logAntState);
|
|
12408
|
+
}
|
|
12388
12409
|
function sizeBasedPRE(state, func) {
|
|
12389
12410
|
if (!func.node.body)
|
|
12390
12411
|
return;
|
|
@@ -12399,14 +12420,7 @@ function sizeBasedPRE(state, func) {
|
|
|
12399
12420
|
if (candidates) {
|
|
12400
12421
|
if (logging) {
|
|
12401
12422
|
console.log(`Found ${candidates.size} candidates in ${func.fullName}`);
|
|
12402
|
-
candidates
|
|
12403
|
-
const defs = Array.from(s.ant).reduce((defs, event) => {
|
|
12404
|
-
if (event.type === "def")
|
|
12405
|
-
defs++;
|
|
12406
|
-
return defs;
|
|
12407
|
-
}, 0);
|
|
12408
|
-
console.log(` - ${declFullName(decl)}: ${candidateCost(s)} bytes, ${s.ant.size - defs} refs, ${defs} defs, ${s.live ? "" : "!"}live`);
|
|
12409
|
-
});
|
|
12423
|
+
logAntDecls(candidates);
|
|
12410
12424
|
}
|
|
12411
12425
|
const nodeMap = new Map();
|
|
12412
12426
|
const declMap = new Map();
|
|
@@ -12652,21 +12666,28 @@ function cloneAnticipatedState(as) {
|
|
|
12652
12666
|
members: new Map(as.members),
|
|
12653
12667
|
};
|
|
12654
12668
|
}
|
|
12669
|
+
function mergeAnticipatedState(ae, be) {
|
|
12670
|
+
mergeSet(ae.ant, be.ant);
|
|
12671
|
+
be.members.forEach((live, block) => ae.members.set(block, live));
|
|
12672
|
+
if (be.live)
|
|
12673
|
+
ae.live = true;
|
|
12674
|
+
}
|
|
12655
12675
|
function cloneAnticipatedDecls(ad) {
|
|
12656
12676
|
const copy = anticipatedDecls();
|
|
12657
12677
|
for (const [k, v] of ad) {
|
|
12658
|
-
|
|
12678
|
+
if (!v.isIsolated) {
|
|
12679
|
+
copy.set(k, cloneAnticipatedState(v));
|
|
12680
|
+
}
|
|
12659
12681
|
}
|
|
12660
12682
|
return copy;
|
|
12661
12683
|
}
|
|
12662
12684
|
function mergeAnticipatedDecls(a, b) {
|
|
12663
12685
|
for (const [k, v] of b) {
|
|
12686
|
+
if (v.isIsolated)
|
|
12687
|
+
continue;
|
|
12664
12688
|
const ae = a.get(k);
|
|
12665
12689
|
if (ae) {
|
|
12666
|
-
|
|
12667
|
-
v.members.forEach((live, block) => ae.members.set(block, live));
|
|
12668
|
-
if (v.live)
|
|
12669
|
-
ae.live = true;
|
|
12690
|
+
mergeAnticipatedState(ae, v);
|
|
12670
12691
|
}
|
|
12671
12692
|
else {
|
|
12672
12693
|
a.set(k, cloneAnticipatedState(v));
|
|
@@ -12680,6 +12701,7 @@ function equalStates(a, b) {
|
|
|
12680
12701
|
const be = b.get(k);
|
|
12681
12702
|
if (!be ||
|
|
12682
12703
|
be.live != ae.live ||
|
|
12704
|
+
be.isIsolated != ae.isIsolated ||
|
|
12683
12705
|
!equalSet(ae.ant, be.ant) ||
|
|
12684
12706
|
!equalMap(ae.members, be.members)) {
|
|
12685
12707
|
return false;
|
|
@@ -12750,7 +12772,8 @@ function candidateCost(candState) {
|
|
|
12750
12772
|
cost += defCost(candState.node);
|
|
12751
12773
|
}
|
|
12752
12774
|
});
|
|
12753
|
-
|
|
12775
|
+
const boundarySize = candidateBoundary(candState).size;
|
|
12776
|
+
cost += defCost(candState.node) * boundarySize;
|
|
12754
12777
|
return cost;
|
|
12755
12778
|
}
|
|
12756
12779
|
function computeAttributes(head) {
|
|
@@ -12888,9 +12911,7 @@ function computeAttributes(head) {
|
|
|
12888
12911
|
if (isUpdate || candidates.live) {
|
|
12889
12912
|
candidates.ant.add(event);
|
|
12890
12913
|
}
|
|
12891
|
-
|
|
12892
|
-
candidates.live = false;
|
|
12893
|
-
}
|
|
12914
|
+
candidates.live = isUpdate;
|
|
12894
12915
|
break;
|
|
12895
12916
|
}
|
|
12896
12917
|
}
|
|
@@ -12899,12 +12920,23 @@ function computeAttributes(head) {
|
|
|
12899
12920
|
curState.forEach((antState) => {
|
|
12900
12921
|
antState.head = top;
|
|
12901
12922
|
antState.members.set(top, antState.live);
|
|
12923
|
+
if (!antState.live && candidateBoundary(antState).size === 0) {
|
|
12924
|
+
// we found a group that's isolated from the rest
|
|
12925
|
+
// of the function. Don't merge it with earlier
|
|
12926
|
+
// refs and defs, because we can take it or leave
|
|
12927
|
+
// it based on its own cost.
|
|
12928
|
+
antState.isIsolated = true;
|
|
12929
|
+
}
|
|
12902
12930
|
});
|
|
12903
12931
|
const oldState = blockStates[top.order];
|
|
12904
12932
|
if (oldState && equalStates(oldState, curState)) {
|
|
12905
12933
|
continue;
|
|
12906
12934
|
}
|
|
12907
12935
|
blockStates[top.order] = curState;
|
|
12936
|
+
if (logging) {
|
|
12937
|
+
console.log(`Updated block ${top.order}`);
|
|
12938
|
+
logAntDecls(curState);
|
|
12939
|
+
}
|
|
12908
12940
|
if (top.preds) {
|
|
12909
12941
|
top.preds.forEach((pred) => enqueue(pred));
|
|
12910
12942
|
}
|
|
@@ -12917,7 +12949,9 @@ function computeAttributes(head) {
|
|
|
12917
12949
|
if (cost >= 0)
|
|
12918
12950
|
return;
|
|
12919
12951
|
const existing = candidateDecls.get(decl);
|
|
12920
|
-
if (!existing ||
|
|
12952
|
+
if (!existing ||
|
|
12953
|
+
existing.isIsolated ||
|
|
12954
|
+
candidateCost(existing) > cost) {
|
|
12921
12955
|
const boundary = candidateBoundary(events);
|
|
12922
12956
|
if (!Array.from(boundary).every((block) => {
|
|
12923
12957
|
if (block !== events.head && block.events) {
|
|
@@ -12957,7 +12991,11 @@ function computeAttributes(head) {
|
|
|
12957
12991
|
return;
|
|
12958
12992
|
}
|
|
12959
12993
|
events.live = false;
|
|
12960
|
-
if (
|
|
12994
|
+
if (existing && existing.isIsolated) {
|
|
12995
|
+
delete existing.isIsolated;
|
|
12996
|
+
mergeAnticipatedState(events, existing);
|
|
12997
|
+
}
|
|
12998
|
+
else if (candidateCost(events) != cost) {
|
|
12961
12999
|
throw new Error(`cost of block ${i} changed`);
|
|
12962
13000
|
}
|
|
12963
13001
|
candidateDecls.set(decl, events);
|
|
@@ -14138,10 +14176,10 @@ async function optimizeMonkeyC(fnMap, barrelList, config) {
|
|
|
14138
14176
|
while (i < node.declarations.length) {
|
|
14139
14177
|
const decl = declarations[i++];
|
|
14140
14178
|
if (decl.init && decl.init.type === "CallExpression") {
|
|
14141
|
-
const inlined = optimizeCall(state, decl.init, decl);
|
|
14179
|
+
const inlined = replace(optimizeCall(state, decl.init, decl), decl.init);
|
|
14142
14180
|
if (!inlined)
|
|
14143
14181
|
continue;
|
|
14144
|
-
if (inlined.type != "BlockStatement") {
|
|
14182
|
+
if (Array.isArray(inlined) || inlined.type != "BlockStatement") {
|
|
14145
14183
|
throw new Error("Unexpected inlined result");
|
|
14146
14184
|
}
|
|
14147
14185
|
if (!results) {
|
|
@@ -14905,7 +14943,7 @@ async function generateOneConfig(buildConfig, dependencyFiles, config) {
|
|
|
14905
14943
|
// the oldest optimized file, we don't need to regenerate
|
|
14906
14944
|
const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
|
|
14907
14945
|
const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
|
|
14908
|
-
if (source_time < opt_time &&
|
|
14946
|
+
if (source_time < opt_time && 1656860602542 < opt_time) {
|
|
14909
14947
|
return { hasTests, diagnostics: prevDiagnostics };
|
|
14910
14948
|
}
|
|
14911
14949
|
}
|
package/package.json
CHANGED