@@ -1316,28 +1316,19 @@ proc replaceInlinedStates(ctx: var Ctx, n: PNode): PNode =
1316
1316
else :
1317
1317
n[i] = ctx.replaceInlinedStates(c)
1318
1318
1319
- proc deleteEmptyStates(ctx: var Ctx) =
1320
- # 1. Assign temporary indexes to state labels to facilitate
1321
- # countStateOccurences. Label number will correspond to index in
1322
- # ctx.states
1319
+ proc optimizeStates(ctx: var Ctx) =
1320
+ # Optimize empty states away and inline inlinable states
1321
+ # This step requires that unique indexes are already assigned to state labels
1323
1322
1324
- # for i in 0 .. ctx.states.high:
1325
- # ctx.states[i].label.intVal = i
1326
-
1327
- # 1. Delete empty states: go through ctx.states,
1328
- # if a state consists only of gotoState node, delete it from states
1329
- # and replace its label index to its target state
1330
-
1331
- # var labelsToReplace = newSeq[(PNode, PNode, bool)]()
1332
-
1333
- # Collect empty states
1323
+ # Find empty states (those consisting only of gotoState node) and mark
1324
+ # them deletable.
1334
1325
for i in 0 .. ctx.states.high:
1335
1326
let s = ctx.states[i]
1336
1327
let body = skipStmtList(s.body)
1337
1328
if body.kind == nkGotoState and body[0 ].kind == nkIntLit and body[0 ].intVal >= 0 :
1338
1329
ctx.states[i].deletable = true
1339
1330
1340
- # Delete empty states
1331
+ # Replace deletable state labels to labels of respective non- empty states
1341
1332
for i in 0 .. ctx.states.high:
1342
1333
ctx.states[i].body = ctx.replaceDeletedStates(ctx.states[i].body)
1343
1334
@@ -1353,18 +1344,15 @@ proc deleteEmptyStates(ctx: var Ctx) =
1353
1344
for i in 0 .. ctx.states.high:
1354
1345
ctx.states[i].label.intVal = i
1355
1346
1356
- # 2. Count state occurences
1347
+ # Count state occurences
1357
1348
var stateOccurences = newSeq[int ](ctx.states.len)
1358
1349
for s in ctx.states:
1359
1350
ctx.countStateOccurences(s.body, stateOccurences)
1360
1351
1361
- var statesToInline = newSeq[ int ]()
1352
+ # If there are inlinable states refered not exactly once, prevent them from inlining
1362
1353
for i, o in stateOccurences:
1363
- if o == 1 and ctx.states[i].inlinable:
1364
- discard
1365
- else :
1354
+ if o != 1 :
1366
1355
ctx.states[i].inlinable = false
1367
- # statesToInline.add(i)
1368
1356
1369
1357
# echo "States to optimize:"
1370
1358
# for i, s in ctx.states:
@@ -1383,7 +1371,7 @@ proc deleteEmptyStates(ctx: var Ctx) =
1383
1371
else :
1384
1372
inc i
1385
1373
1386
- # Reassign state label indexes
1374
+ # Reassign state label indexes one last time
1387
1375
for i in 0 .. ctx.states.high:
1388
1376
ctx.states[i].label.intVal = i
1389
1377
@@ -1484,8 +1472,7 @@ proc transformClosureIterator*(g: ModuleGraph; idgen: IdGenerator; fn: PSym, n:
1484
1472
for i in 0 .. ctx.states.high:
1485
1473
ctx.states[i].label.intVal = i
1486
1474
1487
- # Optimize empty states away
1488
- ctx.deleteEmptyStates()
1475
+ ctx.optimizeStates()
1489
1476
1490
1477
let caseDispatcher = newTreeI(nkCaseStmt, n.info,
1491
1478
ctx.newStateAccess())
0 commit comments