@@ -41,6 +41,7 @@ public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol, TypeDictionary
4141 AST .FuncDecl funcDecl = (AST .FuncDecl ) functionSymbol .functionDecl ;
4242 this .functionType = (Type .TypeFunction ) functionSymbol .type ;
4343 this .registerPool = new RegisterPool ();
44+ // Incremental SSA is an optional feature
4445 this .issa = (options != null && options .contains (Options .ISSA )) ? new IncrementalSSABraun (this ) : new NoopIncrementalSSA ();
4546 setVirtualRegisters (funcDecl .scope );
4647 this .BID = 0 ;
@@ -49,6 +50,7 @@ public CompiledFunction(Symbol.FunctionTypeSymbol functionSymbol, TypeDictionary
4950 this .currentBreakTarget = null ;
5051 this .currentContinueTarget = null ;
5152 this .typeDictionary = typeDictionary ;
53+ issa .sealBlock (entry ); // Incremental SSA is an optional feature
5254 generateArgInstructions (funcDecl .scope );
5355 compileStatement (funcDecl .block );
5456 exitBlockIfNeeded ();
@@ -135,7 +137,7 @@ else if (virtualStack.size() > 1)
135137
136138 public void code (Instruction instruction ) {
137139 currentBlock .add (instruction );
138- instruction .block = currentBlock ;
140+ assert instruction .block = = currentBlock ;
139141 }
140142
141143 private void compileStatement (AST .Stmt statement ) {
@@ -225,12 +227,12 @@ private void compileWhile(AST.WhileStmt whileStmt) {
225227 codeIndexedLoad ();
226228 codeCBR (currentBlock , pop (), bodyBlock , exitBlock );
227229 assert vstackEmpty ();
228- startSealedBlock (bodyBlock ); // ISSA If we seal this here fib test fails, wrong code generated, why?
230+ startSealedBlock (bodyBlock ); // ISSA Body is immediately sealed as no new predecessors possible
229231 compileStatement (whileStmt .stmt );
230232 if (!isBlockTerminated (currentBlock ))
231233 jumpTo (loopHead );
232234 issa .sealBlock (loopHead );
233- startSealedBlock (exitBlock );
235+ startSealedBlock (exitBlock ); // ISSA seal exit block (breaks already done)
234236 currentContinueTarget = savedContinueTarget ;
235237 currentBreakTarget = savedBreakTarget ;
236238 }
@@ -450,7 +452,7 @@ private boolean codeBoolean(AST.BinaryExpr binaryExpr) {
450452 }
451453 startSealedBlock (l1 ); // ISSA seal immediately
452454 compileExpr (binaryExpr .expr2 );
453- var temp = ensureTemp ();
455+ var temp = ensureTemp (); // Normally temps are SSA but this temp gets two assignments, thus must be included during SSA conversion
454456 jumpTo (l3 );
455457 startSealedBlock (l2 ); // ISSA seal immediately
456458 // Below we must write to the same temp
@@ -464,7 +466,7 @@ private boolean codeBoolean(AST.BinaryExpr binaryExpr) {
464466 private boolean compileBinaryExpr (AST .BinaryExpr binaryExpr ) {
465467 String opCode = binaryExpr .op .str ;
466468 if (opCode .equals ("&&" ) ||
467- opCode .equals ("||" )) {
469+ opCode .equals ("||" )) {
468470 return codeBoolean (binaryExpr );
469471 }
470472 boolean indexed = compileExpr (binaryExpr .expr1 );
@@ -476,7 +478,7 @@ private boolean compileBinaryExpr(AST.BinaryExpr binaryExpr) {
476478 Operand right = pop ();
477479 Operand left = pop ();
478480 if (left instanceof Operand .NullConstantOperand &&
479- right instanceof Operand .NullConstantOperand ) {
481+ right instanceof Operand .NullConstantOperand ) {
480482 long value = 0 ;
481483 switch (opCode ) {
482484 case "==" : value = 1 ; break ;
@@ -602,15 +604,17 @@ private Operand top() {
602604 return virtualStack .getLast ();
603605 }
604606
607+ private boolean vstackEmpty () {
608+ return virtualStack .isEmpty ();
609+ }
610+
605611 private Operand .TempRegisterOperand codeIndexedLoad () {
606612 Operand indexed = pop ();
607613 var temp = createTemp (indexed .type );
608- if (indexed instanceof Operand .LoadIndexedOperand loadIndexedOperand ) {
614+ if (indexed instanceof Operand .LoadIndexedOperand loadIndexedOperand )
609615 codeArrayLoad (loadIndexedOperand , temp );
610- }
611- else if (indexed instanceof Operand .LoadFieldOperand loadFieldOperand ) {
616+ else if (indexed instanceof Operand .LoadFieldOperand loadFieldOperand )
612617 codeGetField (loadFieldOperand , temp );
613- }
614618 else
615619 codeMove (indexed , temp );
616620 return temp ;
@@ -619,12 +623,10 @@ else if (indexed instanceof Operand.LoadFieldOperand loadFieldOperand) {
619623 private void codeIndexedStore () {
620624 Operand value = pop ();
621625 Operand indexed = pop ();
622- if (indexed instanceof Operand .LoadIndexedOperand loadIndexedOperand ) {
626+ if (indexed instanceof Operand .LoadIndexedOperand loadIndexedOperand )
623627 codeArrayStore (value , loadIndexedOperand );
624- }
625- else if (indexed instanceof Operand .LoadFieldOperand loadFieldOperand ) {
628+ else if (indexed instanceof Operand .LoadFieldOperand loadFieldOperand )
626629 codeSetField (value , loadFieldOperand );
627- }
628630 else
629631 codeMove (value , indexed );
630632 }
@@ -638,6 +640,15 @@ else if (type instanceof Type.TypeStruct typeStruct)
638640 throw new CompilerException ("Unexpected type: " + type );
639641 }
640642
643+ private void codeStoreAppend () {
644+ var operand = issa .read (pop ());
645+ Operand .RegisterOperand arrayOperand = (Operand .RegisterOperand ) issa .read (top ());
646+ var insn = new Instruction .AStoreAppend (arrayOperand , operand );
647+ issa .recordUse (arrayOperand , insn );
648+ issa .recordUse (operand , insn );
649+ code (insn );
650+ }
651+
641652 private void codeNewArray (Type .TypeArray typeArray ) {
642653 var temp = createTemp (typeArray );
643654 var target = (Operand .RegisterOperand ) issa .write (temp );
@@ -654,15 +665,6 @@ private void codeNewStruct(Type.TypeStruct typeStruct) {
654665 code (insn );
655666 }
656667
657- private void codeStoreAppend () {
658- var operand = issa .read (pop ());
659- Operand .RegisterOperand arrayOperand = (Operand .RegisterOperand ) issa .read (top ());
660- var insn = new Instruction .AStoreAppend (arrayOperand , operand );
661- issa .recordUse (arrayOperand , insn );
662- issa .recordUse (operand , insn );
663- code (insn );
664- }
665-
666668 private void codeArg (Operand .LocalRegisterOperand target ) {
667669 var newtarget = (Operand .RegisterOperand ) issa .write (target );
668670 var insn = new Instruction .ArgInstruction (newtarget );
@@ -774,10 +776,6 @@ private void codeSetField(Operand value, Operand.LoadFieldOperand loadFieldOpera
774776 code (insn );
775777 }
776778
777- private boolean vstackEmpty () {
778- return virtualStack .isEmpty ();
779- }
780-
781779 public StringBuilder toStr (StringBuilder sb , boolean verbose ) {
782780 if (verbose ) {
783781 sb .append (this .functionType .describe ()).append ("\n " );
0 commit comments