@@ -359,24 +359,62 @@ void StackWriter<Mode, Parent>::visitChild(Expression* curr) {
359
359
360
360
template <StackWriterMode Mode, typename Parent>
361
361
void StackWriter<Mode, Parent>::visitBlock(Block* curr) {
362
- if (Mode == StackWriterMode::Binaryen2Stack) {
363
- stackIR.push_back (makeStackInst (StackInst::BlockBegin, curr));
364
- } else {
365
- if (debug) std::cerr << " zz node: Block" << std::endl;
366
- o << int8_t (BinaryConsts::Block);
367
- o << binaryType (curr->type != unreachable ? curr->type : none);
368
- }
369
- breakStack.push_back (curr->name ); // TODO: we don't need to do this in Binaryen2Stack
370
- Index i = 0 ;
371
- for (auto * child : curr->list ) {
372
- if (debug) std::cerr << " " << size_t (curr) << " \n zz Block element " << i++ << std::endl;
373
- visitChild (child);
374
- }
375
- // in Stack2Binary the block ending is in the stream later on
376
- if (Mode == StackWriterMode::Stack2Binary) {
377
- return ;
362
+ auto tilChildren = [this ](Block* curr) {
363
+ if (Mode == StackWriterMode::Binaryen2Stack) {
364
+ stackIR.push_back (makeStackInst (StackInst::BlockBegin, curr));
365
+ } else {
366
+ o << int8_t (BinaryConsts::Block);
367
+ o << binaryType (curr->type != unreachable ? curr->type : none);
368
+ }
369
+ breakStack.push_back (curr->name ); // TODO: we don't need to do this in Binaryen2Stack
370
+ };
371
+ auto visitChildren = [this ](Block* curr, Index from) {
372
+ auto & list = curr->list ;
373
+ while (from < list.size ()) {
374
+ visitChild (list[from++]);
375
+ }
376
+ };
377
+ auto afterChildren = [this ](Block* curr) {
378
+ // in Stack2Binary the block ending is in the stream later on
379
+ if (Mode != StackWriterMode::Stack2Binary) {
380
+ visitBlockEnd (curr);
381
+ }
382
+ };
383
+ // Handle very deeply nested blocks in the first position efficiently,
384
+ // avoiding heavy recursion.
385
+ // We only start to do this if we see it will help us (to avoid allocation
386
+ // of the vector).
387
+ // Note that Stack2Binary mode we don't need to visit children anyhow, so
388
+ // we don't need this optimization.
389
+ if (Mode != StackWriterMode::Stack2Binary) {
390
+ if (!curr->list .empty () && curr->list [0 ]->is <Block>()) {
391
+ std::vector<Block*> parents;
392
+ Block* child;
393
+ while (!curr->list .empty () &&
394
+ (child = curr->list [0 ]->dynCast <Block>())) {
395
+ parents.push_back (curr);
396
+ tilChildren (curr);
397
+ curr = child;
398
+ }
399
+ // Emit the current block, which does not have a block as
400
+ // a child in the first position.
401
+ tilChildren (curr);
402
+ visitChildren (curr, 0 );
403
+ afterChildren (curr);
404
+ // Finish the later parts of all the parent blocks.
405
+ while (!parents.empty ()) {
406
+ auto * parent = parents.back ();
407
+ parents.pop_back ();
408
+ visitChildren (parent, 1 );
409
+ afterChildren (parent);
410
+ }
411
+ return ;
412
+ }
378
413
}
379
- visitBlockEnd (curr);
414
+ // Simple case of not having a nested block in the first position.
415
+ tilChildren (curr);
416
+ visitChildren (curr, 0 );
417
+ afterChildren (curr);
380
418
}
381
419
382
420
template <StackWriterMode Mode, typename Parent>
@@ -403,7 +441,6 @@ void StackWriter<Mode, Parent>::visitBlockEnd(Block* curr) {
403
441
404
442
template <StackWriterMode Mode, typename Parent>
405
443
void StackWriter<Mode, Parent>::visitIf(If* curr) {
406
- if (debug) std::cerr << " zz node: If" << std::endl;
407
444
if (curr->condition ->type == unreachable) {
408
445
// this if-else is unreachable because of the condition, i.e., the condition
409
446
// does not exit. So don't emit the if, but do consume the condition
@@ -465,7 +502,6 @@ void StackWriter<Mode, Parent>::visitIfEnd(If* curr) {
465
502
466
503
template <StackWriterMode Mode, typename Parent>
467
504
void StackWriter<Mode, Parent>::visitLoop(Loop* curr) {
468
- if (debug) std::cerr << " zz node: Loop" << std::endl;
469
505
if (Mode == StackWriterMode::Binaryen2Stack) {
470
506
stackIR.push_back (makeStackInst (StackInst::LoopBegin, curr));
471
507
} else {
@@ -502,7 +538,6 @@ void StackWriter<Mode, Parent>::visitLoopEnd(Loop* curr) {
502
538
503
539
template <StackWriterMode Mode, typename Parent>
504
540
void StackWriter<Mode, Parent>::visitBreak(Break* curr) {
505
- if (debug) std::cerr << " zz node: Break" << std::endl;
506
541
if (curr->value ) {
507
542
visitChild (curr->value );
508
543
}
@@ -525,7 +560,6 @@ void StackWriter<Mode, Parent>::visitBreak(Break* curr) {
525
560
526
561
template <StackWriterMode Mode, typename Parent>
527
562
void StackWriter<Mode, Parent>::visitSwitch(Switch* curr) {
528
- if (debug) std::cerr << " zz node: Switch" << std::endl;
529
563
if (curr->value ) {
530
564
visitChild (curr->value );
531
565
}
@@ -547,7 +581,6 @@ void StackWriter<Mode, Parent>::visitSwitch(Switch* curr) {
547
581
548
582
template <StackWriterMode Mode, typename Parent>
549
583
void StackWriter<Mode, Parent>::visitCall(Call* curr) {
550
- if (debug) std::cerr << " zz node: Call" << std::endl;
551
584
for (auto * operand : curr->operands ) {
552
585
visitChild (operand);
553
586
}
@@ -561,7 +594,6 @@ void StackWriter<Mode, Parent>::visitCall(Call* curr) {
561
594
562
595
template <StackWriterMode Mode, typename Parent>
563
596
void StackWriter<Mode, Parent>::visitCallIndirect(CallIndirect* curr) {
564
- if (debug) std::cerr << " zz node: CallIndirect" << std::endl;
565
597
for (auto * operand : curr->operands ) {
566
598
visitChild (operand);
567
599
}
@@ -578,14 +610,12 @@ void StackWriter<Mode, Parent>::visitCallIndirect(CallIndirect* curr) {
578
610
579
611
template <StackWriterMode Mode, typename Parent>
580
612
void StackWriter<Mode, Parent>::visitGetLocal(GetLocal* curr) {
581
- if (debug) std::cerr << " zz node: GetLocal " << (o.size () + 1 ) << std::endl;
582
613
if (justAddToStack (curr)) return ;
583
614
o << int8_t (BinaryConsts::GetLocal) << U32LEB (mappedLocals[curr->index ]);
584
615
}
585
616
586
617
template <StackWriterMode Mode, typename Parent>
587
618
void StackWriter<Mode, Parent>::visitSetLocal(SetLocal* curr) {
588
- if (debug) std::cerr << " zz node: Set|TeeLocal" << std::endl;
589
619
visitChild (curr->value );
590
620
if (!justAddToStack (curr)) {
591
621
o << int8_t (curr->isTee () ? BinaryConsts::TeeLocal : BinaryConsts::SetLocal) << U32LEB (mappedLocals[curr->index ]);
@@ -597,22 +627,19 @@ void StackWriter<Mode, Parent>::visitSetLocal(SetLocal* curr) {
597
627
598
628
template <StackWriterMode Mode, typename Parent>
599
629
void StackWriter<Mode, Parent>::visitGetGlobal(GetGlobal* curr) {
600
- if (debug) std::cerr << " zz node: GetGlobal " << (o.size () + 1 ) << std::endl;
601
630
if (justAddToStack (curr)) return ;
602
631
o << int8_t (BinaryConsts::GetGlobal) << U32LEB (parent.getGlobalIndex (curr->name ));
603
632
}
604
633
605
634
template <StackWriterMode Mode, typename Parent>
606
635
void StackWriter<Mode, Parent>::visitSetGlobal(SetGlobal* curr) {
607
- if (debug) std::cerr << " zz node: SetGlobal" << std::endl;
608
636
visitChild (curr->value );
609
637
if (justAddToStack (curr)) return ;
610
638
o << int8_t (BinaryConsts::SetGlobal) << U32LEB (parent.getGlobalIndex (curr->name ));
611
639
}
612
640
613
641
template <StackWriterMode Mode, typename Parent>
614
642
void StackWriter<Mode, Parent>::visitLoad(Load* curr) {
615
- if (debug) std::cerr << " zz node: Load" << std::endl;
616
643
visitChild (curr->ptr );
617
644
if (curr->type == unreachable) {
618
645
// don't even emit it; we don't know the right type
@@ -678,7 +705,6 @@ void StackWriter<Mode, Parent>::visitLoad(Load* curr) {
678
705
679
706
template <StackWriterMode Mode, typename Parent>
680
707
void StackWriter<Mode, Parent>::visitStore(Store* curr) {
681
- if (debug) std::cerr << " zz node: Store" << std::endl;
682
708
visitChild (curr->ptr );
683
709
visitChild (curr->value );
684
710
if (curr->type == unreachable) {
@@ -744,7 +770,6 @@ void StackWriter<Mode, Parent>::visitStore(Store* curr) {
744
770
745
771
template <StackWriterMode Mode, typename Parent>
746
772
void StackWriter<Mode, Parent>::visitAtomicRMW(AtomicRMW* curr) {
747
- if (debug) std::cerr << " zz node: AtomicRMW" << std::endl;
748
773
visitChild (curr->ptr );
749
774
// stop if the rest isn't reachable anyhow
750
775
if (curr->ptr ->type == unreachable) return ;
@@ -799,7 +824,6 @@ void StackWriter<Mode, Parent>::visitAtomicRMW(AtomicRMW* curr) {
799
824
800
825
template <StackWriterMode Mode, typename Parent>
801
826
void StackWriter<Mode, Parent>::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
802
- if (debug) std::cerr << " zz node: AtomicCmpxchg" << std::endl;
803
827
visitChild (curr->ptr );
804
828
// stop if the rest isn't reachable anyhow
805
829
if (curr->ptr ->type == unreachable) return ;
@@ -840,7 +864,6 @@ void StackWriter<Mode, Parent>::visitAtomicCmpxchg(AtomicCmpxchg* curr) {
840
864
841
865
template <StackWriterMode Mode, typename Parent>
842
866
void StackWriter<Mode, Parent>::visitAtomicWait(AtomicWait* curr) {
843
- if (debug) std::cerr << " zz node: AtomicWait" << std::endl;
844
867
visitChild (curr->ptr );
845
868
// stop if the rest isn't reachable anyhow
846
869
if (curr->ptr ->type == unreachable) return ;
@@ -868,7 +891,6 @@ void StackWriter<Mode, Parent>::visitAtomicWait(AtomicWait* curr) {
868
891
869
892
template <StackWriterMode Mode, typename Parent>
870
893
void StackWriter<Mode, Parent>::visitAtomicWake(AtomicWake* curr) {
871
- if (debug) std::cerr << " zz node: AtomicWake" << std::endl;
872
894
visitChild (curr->ptr );
873
895
// stop if the rest isn't reachable anyhow
874
896
if (curr->ptr ->type == unreachable) return ;
@@ -1001,7 +1023,6 @@ void StackWriter<Mode, Parent>::visitMemoryFill(MemoryFill* curr) {
1001
1023
1002
1024
template <StackWriterMode Mode, typename Parent>
1003
1025
void StackWriter<Mode, Parent>::visitConst(Const* curr) {
1004
- if (debug) std::cerr << " zz node: Const" << curr << " : " << curr->type << std::endl;
1005
1026
if (justAddToStack (curr)) return ;
1006
1027
switch (curr->type ) {
1007
1028
case i32: {
@@ -1032,12 +1053,10 @@ void StackWriter<Mode, Parent>::visitConst(Const* curr) {
1032
1053
case unreachable:
1033
1054
WASM_UNREACHABLE ();
1034
1055
}
1035
- if (debug) std::cerr << " zz const node done.\n " ;
1036
1056
}
1037
1057
1038
1058
template <StackWriterMode Mode, typename Parent>
1039
1059
void StackWriter<Mode, Parent>::visitUnary(Unary* curr) {
1040
- if (debug) std::cerr << " zz node: Unary" << std::endl;
1041
1060
visitChild (curr->value );
1042
1061
if (curr->type == unreachable) {
1043
1062
emitExtraUnreachable ();
@@ -1144,7 +1163,6 @@ void StackWriter<Mode, Parent>::visitUnary(Unary* curr) {
1144
1163
1145
1164
template <StackWriterMode Mode, typename Parent>
1146
1165
void StackWriter<Mode, Parent>::visitBinary(Binary* curr) {
1147
- if (debug) std::cerr << " zz node: Binary" << std::endl;
1148
1166
visitChild (curr->left );
1149
1167
visitChild (curr->right );
1150
1168
if (curr->type == unreachable) {
@@ -1317,7 +1335,6 @@ void StackWriter<Mode, Parent>::visitBinary(Binary* curr) {
1317
1335
1318
1336
template <StackWriterMode Mode, typename Parent>
1319
1337
void StackWriter<Mode, Parent>::visitSelect(Select* curr) {
1320
- if (debug) std::cerr << " zz node: Select" << std::endl;
1321
1338
visitChild (curr->ifTrue );
1322
1339
visitChild (curr->ifFalse );
1323
1340
visitChild (curr->condition );
@@ -1331,7 +1348,6 @@ void StackWriter<Mode, Parent>::visitSelect(Select* curr) {
1331
1348
1332
1349
template <StackWriterMode Mode, typename Parent>
1333
1350
void StackWriter<Mode, Parent>::visitReturn(Return* curr) {
1334
- if (debug) std::cerr << " zz node: Return" << std::endl;
1335
1351
if (curr->value ) {
1336
1352
visitChild (curr->value );
1337
1353
}
@@ -1342,7 +1358,6 @@ void StackWriter<Mode, Parent>::visitReturn(Return* curr) {
1342
1358
1343
1359
template <StackWriterMode Mode, typename Parent>
1344
1360
void StackWriter<Mode, Parent>::visitHost(Host* curr) {
1345
- if (debug) std::cerr << " zz node: Host" << std::endl;
1346
1361
switch (curr->op ) {
1347
1362
case CurrentMemory: {
1348
1363
break ;
@@ -1368,21 +1383,18 @@ void StackWriter<Mode, Parent>::visitHost(Host* curr) {
1368
1383
1369
1384
template <StackWriterMode Mode, typename Parent>
1370
1385
void StackWriter<Mode, Parent>::visitNop(Nop* curr) {
1371
- if (debug) std::cerr << " zz node: Nop" << std::endl;
1372
1386
if (justAddToStack (curr)) return ;
1373
1387
o << int8_t (BinaryConsts::Nop);
1374
1388
}
1375
1389
1376
1390
template <StackWriterMode Mode, typename Parent>
1377
1391
void StackWriter<Mode, Parent>::visitUnreachable(Unreachable* curr) {
1378
- if (debug) std::cerr << " zz node: Unreachable" << std::endl;
1379
1392
if (justAddToStack (curr)) return ;
1380
1393
o << int8_t (BinaryConsts::Unreachable);
1381
1394
}
1382
1395
1383
1396
template <StackWriterMode Mode, typename Parent>
1384
1397
void StackWriter<Mode, Parent>::visitDrop(Drop* curr) {
1385
- if (debug) std::cerr << " zz node: Drop" << std::endl;
1386
1398
visitChild (curr->value );
1387
1399
if (justAddToStack (curr)) return ;
1388
1400
o << int8_t (BinaryConsts::Drop);
0 commit comments