18
18
#include " simple_instruction_list.h"
19
19
#include " utils/FormalArgs.h"
20
20
21
+ #include < initializer_list>
21
22
#include < sstream>
22
23
#include < unordered_map>
23
24
#include < vector>
@@ -333,6 +334,10 @@ class RBCCode {
333
334
bool operator ==(const Iterator& other) const {
334
335
return pos == other.pos ;
335
336
}
337
+ size_t operator -(const Iterator& other) const {
338
+ assert (pos >= other.pos );
339
+ return pos - other.pos ;
340
+ }
336
341
337
342
size_t label (const Iterator& begin) const {
338
343
return pos - begin.pos + 1 ;
@@ -370,26 +375,67 @@ class RBCCode {
370
375
371
376
struct Stack {
372
377
private:
373
- std::stack <Value*> stack;
378
+ std::vector <Value*> stack;
374
379
375
380
public:
376
- void push (Value* v) { stack.push (v); }
381
+ void push (Value* v) { stack.push_back (v); }
377
382
Value* pop () {
378
- auto v = stack.top ();
379
- stack.pop ();
383
+ auto v = stack.back ();
384
+ stack.pop_back ();
380
385
return v;
381
386
}
382
- ~Stack () { assert (stack.empty ()); }
387
+ bool isEmpty () const { return stack.empty (); }
388
+ friend struct CompilerInfo ;
383
389
};
384
390
385
391
struct CompilerInfo {
386
392
CompilerInfo (SEXP src, Stack& stack, Builder& insert)
387
- : src(src), stack(stack), insert(insert) {}
393
+ : src(src), stack(stack), insert(insert) {
394
+ basicBlocks[1 ] = insert.getCurrentBB ();
395
+ }
396
+ BB* getBB (size_t pos) {
397
+ auto f = basicBlocks.find (pos);
398
+ if (f != basicBlocks.end ())
399
+ return f->second ;
400
+ return basicBlocks
401
+ .emplace (pos, new BB (insert.code , insert.code ->nextBBId ++))
402
+ .first ->second ;
403
+ }
388
404
SEXP src;
389
405
Stack& stack;
390
406
Builder& insert;
391
407
std::unordered_set<size_t > mergepoints;
408
+ std::unordered_map<BB*, Stack> bbState;
409
+ std::unordered_map<size_t , BB*> basicBlocks;
392
410
std::unordered_map<size_t , size_t > jumps;
411
+
412
+ void merge (std::initializer_list<size_t > trgs) {
413
+ for (auto trg : trgs) {
414
+ auto bb = getBB (trg);
415
+ if (!mergepoints.count (trg)) {
416
+ assert (!bbState.count (bb));
417
+ bbState[bb] = stack;
418
+ continue ;
419
+ }
420
+
421
+ auto state = bbState.find (bb);
422
+ if (state == bbState.end ()) {
423
+ Stack trgStack;
424
+ for (auto v : stack.stack ) {
425
+ trgStack.push (*bb->insert (
426
+ bb->end (), new Phi ({{insert.getCurrentBB (), v}})));
427
+ }
428
+ bbState.emplace (bb, trgStack);
429
+ } else {
430
+ Stack& trgStack = state->second ;
431
+ for (size_t pos = 0 ; pos < trgStack.stack .size (); ++pos) {
432
+ Phi::Cast (trgStack.stack [pos])
433
+ ->addInput (insert.getCurrentBB (), stack.stack [pos]);
434
+ }
435
+ }
436
+ }
437
+ stack.stack .clear ();
438
+ }
393
439
};
394
440
395
441
static void findMerges (const RBCCode& bytecode, CompilerInfo& info) {
@@ -430,6 +476,7 @@ struct BCCompiler {
430
476
431
477
void push (Value* v) { cmp.stack .push (v); }
432
478
479
+ bool stackEmpty () { return cmp.stack .isEmpty (); }
433
480
Value* pop () { return cmp.stack .pop (); }
434
481
435
482
Instruction* insertPush (Instruction* i) {
@@ -447,34 +494,74 @@ struct BCCompiler {
447
494
Value* env () { return cmp.insert .env ; }
448
495
449
496
template <RBC::Id BC>
450
- void compile (const RBC&);
497
+ void compile (const RBC&, size_t pos );
451
498
};
452
499
453
500
// Start instructions translation
454
501
455
502
template <>
456
- void BCCompiler::compile<RBC::GETVAR_OP>(const RBC& bc) {
503
+ void BCCompiler::compile<RBC::GETVAR_OP>(const RBC& bc, size_t pos ) {
457
504
auto v = insert (new LdVar (cnst (bc.imm (0 )), env ()));
458
505
insertPush (new Force (v, env (), Tombstone::framestate ()));
459
506
}
460
507
461
508
template <>
462
- void BCCompiler::compile<RBC::RETURN_OP>(const RBC& bc) {
509
+ void BCCompiler::compile<RBC::RETURN_OP>(const RBC& bc, size_t pos ) {
463
510
insert (new Return (pop ()));
464
511
}
465
512
466
513
template <>
467
- void BCCompiler::compile<RBC::LDCONST_OP>(const RBC& bc) {
514
+ void BCCompiler::compile<RBC::LDCONST_OP>(const RBC& bc, size_t pos ) {
468
515
push (insert (new LdConst (cnst (bc.imm (0 )))));
469
516
}
470
517
471
518
template <>
472
- void BCCompiler::compile<RBC::ADD_OP>(const RBC& bc) {
519
+ void BCCompiler::compile<RBC::ADD_OP>(const RBC& bc, size_t pos ) {
473
520
auto a = pop ();
474
521
auto b = pop ();
475
522
insertPush (new Add (a, b, env (), bc.imm (0 )));
476
523
}
477
524
525
+ template <>
526
+ void BCCompiler::compile<RBC::BRIFNOT_OP>(const RBC& bc, size_t pos) {
527
+ auto t = insert (new CheckTrueFalse (pop ()));
528
+ auto label = bc.imm (1 );
529
+ insert (new Branch (t));
530
+ auto fallPos = pos + bc.imm () + 1 ;
531
+ auto fall = cmp.getBB (fallPos);
532
+ auto trg = cmp.getBB (label);
533
+ cmp.insert .setBranch (fall, trg);
534
+ cmp.merge ({fallPos, (size_t )label});
535
+ }
536
+
537
+ template <>
538
+ void BCCompiler::compile<RBC::GOTO_OP>(const RBC& bc, size_t pos) {
539
+ auto label = bc.imm (0 );
540
+ auto trg = cmp.getBB (label);
541
+ cmp.insert .setNext (trg);
542
+ cmp.merge ({(size_t )label});
543
+ }
544
+
545
+ template <>
546
+ void BCCompiler::compile<RBC::LDNULL_OP>(const RBC& bc, size_t pos) {
547
+ push (Nil::instance ());
548
+ }
549
+
550
+ template <>
551
+ void BCCompiler::compile<RBC::INVISIBLE_OP>(const RBC& bc, size_t pos) {
552
+ insert (new Invisible ());
553
+ }
554
+
555
+ template <>
556
+ void BCCompiler::compile<RBC::INCLNK_OP>(const RBC& bc, size_t pos) {
557
+ insert (new Invisible ());
558
+ }
559
+
560
+ template <>
561
+ void BCCompiler::compile<RBC::DECLNK_OP>(const RBC& bc, size_t pos) {
562
+ insert (new Invisible ());
563
+ }
564
+
478
565
// End instructions translation
479
566
480
567
pir::ClosureVersion* Gnur2Pir::compile (SEXP src, const std::string& name) {
@@ -502,25 +589,169 @@ pir::ClosureVersion* Gnur2Pir::compile(SEXP src, const std::string& name) {
502
589
BCCompiler bccompiler (info);
503
590
504
591
#define SUPPORTED_INSTRUCTIONS (V ) \
592
+ V (RBC::GOTO_OP) \
505
593
V (RBC::GETVAR_OP) \
506
594
V (RBC::RETURN_OP) \
507
595
V (RBC::LDCONST_OP) \
508
- V (RBC::ADD_OP)
596
+ V (RBC::ADD_OP) \
597
+ V (RBC::LDNULL_OP) \
598
+ V (RBC::INVISIBLE_OP) \
599
+ V (RBC::INCLNK_OP) \
600
+ V (RBC::DECLNK_OP) \
601
+ V (RBC::BRIFNOT_OP)
602
+
603
+ #define UNSUPPORTED_INSTRUCTIONS (V ) \
604
+ V (RBC::BCMISMATCH_OP) \
605
+ V (RBC::POP_OP) \
606
+ V (RBC::DUP_OP) \
607
+ V (RBC::PRINTVALUE_OP) \
608
+ V (RBC::STARTLOOPCNTXT_OP) \
609
+ V (RBC::ENDLOOPCNTXT_OP) \
610
+ V (RBC::DOLOOPNEXT_OP) \
611
+ V (RBC::DOLOOPBREAK_OP) \
612
+ V (RBC::STARTFOR_OP) \
613
+ V (RBC::STEPFOR_OP) \
614
+ V (RBC::ENDFOR_OP) \
615
+ V (RBC::SETLOOPVAL_OP) \
616
+ V (RBC::LDTRUE_OP) \
617
+ V (RBC::LDFALSE_OP) \
618
+ V (RBC::DDVAL_OP) \
619
+ V (RBC::SETVAR_OP) \
620
+ V (RBC::GETFUN_OP) \
621
+ V (RBC::GETGLOBFUN_OP) \
622
+ V (RBC::GETSYMFUN_OP) \
623
+ V (RBC::GETBUILTIN_OP) \
624
+ V (RBC::GETINTLBUILTIN_OP) \
625
+ V (RBC::CHECKFUN_OP) \
626
+ V (RBC::MAKEPROM_OP) \
627
+ V (RBC::DOMISSING_OP) \
628
+ V (RBC::SETTAG_OP) \
629
+ V (RBC::DODOTS_OP) \
630
+ V (RBC::PUSHARG_OP) \
631
+ V (RBC::PUSHCONSTARG_OP) \
632
+ V (RBC::PUSHNULLARG_OP) \
633
+ V (RBC::PUSHTRUEARG_OP) \
634
+ V (RBC::PUSHFALSEARG_OP) \
635
+ V (RBC::CALL_OP) \
636
+ V (RBC::CALLBUILTIN_OP) \
637
+ V (RBC::CALLSPECIAL_OP) \
638
+ V (RBC::MAKECLOSURE_OP) \
639
+ V (RBC::UMINUS_OP) \
640
+ V (RBC::UPLUS_OP) \
641
+ V (RBC::SUB_OP) \
642
+ V (RBC::MUL_OP) \
643
+ V (RBC::DIV_OP) \
644
+ V (RBC::EXPT_OP) \
645
+ V (RBC::SQRT_OP) \
646
+ V (RBC::EXP_OP) \
647
+ V (RBC::EQ_OP) \
648
+ V (RBC::NE_OP) \
649
+ V (RBC::LT_OP) \
650
+ V (RBC::LE_OP) \
651
+ V (RBC::GE_OP) \
652
+ V (RBC::GT_OP) \
653
+ V (RBC::AND_OP) \
654
+ V (RBC::OR_OP) \
655
+ V (RBC::NOT_OP) \
656
+ V (RBC::DOTSERR_OP) \
657
+ V (RBC::STARTASSIGN_OP) \
658
+ V (RBC::ENDASSIGN_OP) \
659
+ V (RBC::STARTSUBSET_OP) \
660
+ V (RBC::DFLTSUBSET_OP) \
661
+ V (RBC::STARTSUBASSIGN_OP) \
662
+ V (RBC::DFLTSUBASSIGN_OP) \
663
+ V (RBC::STARTC_OP) \
664
+ V (RBC::DFLTC_OP) \
665
+ V (RBC::STARTSUBSET2_OP) \
666
+ V (RBC::DFLTSUBSET2_OP) \
667
+ V (RBC::STARTSUBASSIGN2_OP) \
668
+ V (RBC::DFLTSUBASSIGN2_OP) \
669
+ V (RBC::DOLLAR_OP) \
670
+ V (RBC::DOLLARGETS_OP) \
671
+ V (RBC::ISNULL_OP) \
672
+ V (RBC::ISLOGICAL_OP) \
673
+ V (RBC::ISINTEGER_OP) \
674
+ V (RBC::ISDOUBLE_OP) \
675
+ V (RBC::ISCOMPLEX_OP) \
676
+ V (RBC::ISCHARACTER_OP) \
677
+ V (RBC::ISSYMBOL_OP) \
678
+ V (RBC::ISOBJECT_OP) \
679
+ V (RBC::ISNUMERIC_OP) \
680
+ V (RBC::VECSUBSET_OP) \
681
+ V (RBC::MATSUBSET_OP) \
682
+ V (RBC::VECSUBASSIGN_OP) \
683
+ V (RBC::MATSUBASSIGN_OP) \
684
+ V (RBC::AND1ST_OP) \
685
+ V (RBC::AND2ND_OP) \
686
+ V (RBC::OR1ST_OP) \
687
+ V (RBC::OR2ND_OP) \
688
+ V (RBC::GETVAR_MISSOK_OP) \
689
+ V (RBC::DDVAL_MISSOK_OP) \
690
+ V (RBC::VISIBLE_OP) \
691
+ V (RBC::SETVAR2_OP) \
692
+ V (RBC::STARTASSIGN2_OP) \
693
+ V (RBC::ENDASSIGN2_OP) \
694
+ V (RBC::SETTER_CALL_OP) \
695
+ V (RBC::GETTER_CALL_OP) \
696
+ V (RBC::SWAP_OP) \
697
+ V (RBC::DUP2ND_OP) \
698
+ V (RBC::SWITCH_OP) \
699
+ V (RBC::RETURNJMP_OP) \
700
+ V (RBC::STARTSUBSET_N_OP) \
701
+ V (RBC::STARTSUBASSIGN_N_OP) \
702
+ V (RBC::VECSUBSET2_OP) \
703
+ V (RBC::MATSUBSET2_OP) \
704
+ V (RBC::VECSUBASSIGN2_OP) \
705
+ V (RBC::MATSUBASSIGN2_OP) \
706
+ V (RBC::STARTSUBSET2_N_OP) \
707
+ V (RBC::STARTSUBASSIGN2_N_OP) \
708
+ V (RBC::SUBSET_N_OP) \
709
+ V (RBC::SUBSET2_N_OP) \
710
+ V (RBC::SUBASSIGN_N_OP) \
711
+ V (RBC::SUBASSIGN2_N_OP) \
712
+ V (RBC::LOG_OP) \
713
+ V (RBC::LOGBASE_OP) \
714
+ V (RBC::MATH1_OP) \
715
+ V (RBC::DOTCALL_OP) \
716
+ V (RBC::COLON_OP) \
717
+ V (RBC::SEQALONG_OP) \
718
+ V (RBC::SEQLEN_OP) \
719
+ V (RBC::BASEGUARD_OP) \
720
+ V (RBC::DECLNK_N_OP)
509
721
510
722
for (auto pc = bytecode.begin (); pc != bytecode.end (); ++pc) {
511
723
auto bc = *pc;
724
+ auto pos = (pc - bytecode.begin ()) + 1 ;
725
+ auto hasBB = info.basicBlocks .find (pos);
726
+ if (hasBB != info.basicBlocks .end ()) {
727
+ info.insert .reenterBB (hasBB->second );
728
+ auto state = info.bbState .find (hasBB->second );
729
+ if (state != info.bbState .end ())
730
+ info.stack = state->second ;
731
+ }
732
+
512
733
switch (bc.id ) {
513
734
#define V (BC ) \
514
735
case BC: \
515
- bccompiler.compile <BC>(bc); \
736
+ bccompiler.compile <BC>(bc, pos); \
516
737
break ;
517
738
SUPPORTED_INSTRUCTIONS (V)
518
739
#undef V
519
740
520
- default :
521
- std::cerr << " Could not compile " << *pc << " \n " ;
522
- assert (false );
523
- return nullptr ;
741
+ #define V (BC ) \
742
+ case BC: \
743
+ std::cerr << " Could not compile " << *pc << " \n " ; \
744
+ assert (false ); \
745
+ return nullptr ;
746
+ UNSUPPORTED_INSTRUCTIONS (V)
747
+ #undef V
748
+ }
749
+
750
+ auto next = pos + 1 + bc.imm ();
751
+ if (bc.falls () && info.mergepoints .count (next) &&
752
+ !info.stack .isEmpty ()) {
753
+ info.merge ({next});
754
+ info.insert .getCurrentBB ()->setNext (info.getBB (next));
524
755
}
525
756
}
526
757
return v;
0 commit comments