@@ -200,36 +200,38 @@ private void compileExprStmt(AST.ExprStmt exprStmt) {
200200 private void compileContinue (AST .ContinueStmt continueStmt ) {
201201 if (currentContinueTarget == null )
202202 throw new CompilerException ("No continue target found" );
203+ assert !issa .isSealed (currentContinueTarget );
203204 jumpTo (currentContinueTarget );
204205 }
205206
206207 private void compileBreak (AST .BreakStmt breakStmt ) {
207208 if (currentBreakTarget == null )
208209 throw new CompilerException ("No break target found" );
210+ assert !issa .isSealed (currentBreakTarget );
209211 jumpTo (currentBreakTarget );
210212 }
211213
212214 private void compileWhile (AST .WhileStmt whileStmt ) {
213- BasicBlock loopBlock = createLoopHead ();
215+ BasicBlock loopHead = createLoopHead ();
214216 BasicBlock bodyBlock = createBlock ();
215217 BasicBlock exitBlock = createBlock ();
216218 BasicBlock savedBreakTarget = currentBreakTarget ;
217219 BasicBlock savedContinueTarget = currentContinueTarget ;
218220 currentBreakTarget = exitBlock ;
219- currentContinueTarget = loopBlock ;
220- startBlock (loopBlock );
221+ currentContinueTarget = loopHead ;
222+ startBlock (loopHead ); // ISSA cannot seal until all back edges done
221223 boolean indexed = compileExpr (whileStmt .condition );
222224 if (indexed )
223225 codeIndexedLoad ();
224226 codeCBR (currentBlock , pop (), bodyBlock , exitBlock );
225227 assert vstackEmpty ();
226- startBlock (bodyBlock );
228+ startBlock (bodyBlock ); // ISSA If we seal this here fib test fails, wrong code generated, why?
227229 compileStatement (whileStmt .stmt );
228230 if (!isBlockTerminated (currentBlock ))
229- jumpTo (loopBlock );
230- issa .sealBlock (currentBlock );
231- startBlock ( exitBlock );
232- issa . sealBlock ( loopBlock );
231+ jumpTo (loopHead );
232+ issa .sealBlock (bodyBlock );
233+ issa . sealBlock ( loopHead );
234+ startSealedBlock ( exitBlock );
233235 currentContinueTarget = savedContinueTarget ;
234236 currentBreakTarget = savedBreakTarget ;
235237 }
@@ -241,9 +243,9 @@ private boolean isBlockTerminated(BasicBlock block) {
241243
242244 public void jumpTo (BasicBlock block ) {
243245 assert !isBlockTerminated (currentBlock );
246+ assert !issa .isSealed (block );
244247 currentBlock .add (new Instruction .Jump (block ));
245248 currentBlock .addSuccessor (block );
246- issa .sealBlock (currentBlock );
247249 }
248250
249251 public void startBlock (BasicBlock block ) {
@@ -252,31 +254,32 @@ public void startBlock(BasicBlock block) {
252254 }
253255 currentBlock = block ;
254256 }
255-
257+ public void startSealedBlock (BasicBlock block ) {
258+ startBlock (block );
259+ assert !issa .isSealed (currentBlock );
260+ issa .sealBlock (currentBlock );
261+ }
256262 private void compileIf (AST .IfElseStmt ifElseStmt ) {
257- BasicBlock ifBlock = createBlock ();
263+ BasicBlock thenBlock = createBlock ();
258264 boolean needElse = ifElseStmt .elseStmt != null ;
259265 BasicBlock elseBlock = needElse ? createBlock () : null ;
260266 BasicBlock exitBlock = createBlock ();
261267 boolean indexed = compileExpr (ifElseStmt .condition );
262268 if (indexed )
263269 codeIndexedLoad ();
264- codeCBR (currentBlock , pop (), ifBlock , needElse ? elseBlock : exitBlock );
265- issa .sealBlock (currentBlock );
270+ codeCBR (currentBlock , pop (), thenBlock , needElse ? elseBlock : exitBlock );
266271 assert vstackEmpty ();
267- startBlock (ifBlock );
268- issa .sealBlock (ifBlock );
272+ startSealedBlock (thenBlock ); // ISSA seal immediately
269273 compileStatement (ifElseStmt .ifStmt );
270274 if (!isBlockTerminated (currentBlock ))
271275 jumpTo (exitBlock );
272276 if (elseBlock != null ) {
273- startBlock (elseBlock );
274- issa .sealBlock (elseBlock );
277+ startSealedBlock (elseBlock ); // ISSA seal immediately
275278 compileStatement (ifElseStmt .elseStmt );
276279 if (!isBlockTerminated (currentBlock ))
277280 jumpTo (exitBlock );
278281 }
279- startBlock (exitBlock );
282+ startSealedBlock (exitBlock ); // ISSA seal immediately
280283 }
281284
282285 private void compileLet (AST .VarStmt letStmt ) {
@@ -446,16 +449,15 @@ private boolean codeBoolean(AST.BinaryExpr binaryExpr) {
446449 } else {
447450 codeCBR (currentBlock , pop (), l2 , l1 );
448451 }
449- issa .sealBlock (currentBlock );
450- startBlock (l1 );
452+ startSealedBlock (l1 ); // ISSA seal immediately
451453 compileExpr (binaryExpr .expr2 );
452454 var temp = ensureTemp ();
453455 jumpTo (l3 );
454- startBlock (l2 );
456+ startSealedBlock (l2 ); // ISSA seal immediately
455457 // Below we must write to the same temp
456458 codeMove (new Operand .ConstantOperand (isAnd ? 0 : 1 , typeDictionary .INT ), temp );
457459 jumpTo (l3 );
458- startBlock (l3 );
460+ startSealedBlock (l3 ); // ISSA seal immediately
459461 // leave temp on virtual stack
460462 return false ;
461463 }
@@ -688,6 +690,10 @@ private void codeReturn(Operand resultOperand) {
688690 private void codeCBR (BasicBlock block , Operand condition , BasicBlock trueBlock , BasicBlock falseBlock ) {
689691 condition = issa .read (condition );
690692 var insn = new Instruction .ConditionalBranch (block , condition , trueBlock , falseBlock );
693+ assert !issa .isSealed (trueBlock );
694+ assert !issa .isSealed (falseBlock );
695+ block .addSuccessor (trueBlock );
696+ block .addSuccessor (falseBlock );
691697 issa .recordUse (condition , insn );
692698 code (insn );
693699 }
@@ -818,6 +824,7 @@ interface IncrementalSSA {
818824 void recordDef (Register reg , Instruction instruction );
819825 void recordDef (Operand operand , Instruction instruction );
820826 void sealBlock (BasicBlock block );
827+ boolean isSealed (BasicBlock block );
821828 void finish (EnumSet <Options > options );
822829 }
823830
@@ -925,6 +932,7 @@ private Instruction.Phi makePhi(Register val, BasicBlock block) {
925932 * Populate the members of a phi instruction
926933 */
927934 private Register addPhiOperands (Register variable , Instruction .Phi phi ) {
935+ assert phi .numInputs () == 0 ;
928936 // Determine operands from predecessors
929937 for (BasicBlock pred : phi .block .predecessors ) {
930938 phi .addInput (readVariable (variable ,pred ));
@@ -1059,6 +1067,8 @@ public void recordDef(Operand operand, Instruction instruction) {
10591067 }
10601068 @ Override
10611069 public void sealBlock (BasicBlock block ) {
1070+ if (isSealed (block ))
1071+ return ;
10621072 var pendingPhis = incompletePhis .remove (block );
10631073 if (pendingPhis != null ) {
10641074 for (var variable : pendingPhis .keySet ()) {
@@ -1068,6 +1078,10 @@ public void sealBlock(BasicBlock block) {
10681078 sealedBlocks .set (block .bid );
10691079 }
10701080 @ Override
1081+ public boolean isSealed (BasicBlock block ) {
1082+ return sealedBlocks .get (block .bid );
1083+ }
1084+ @ Override
10711085 public void finish (EnumSet <Options > options ) {
10721086 function .isSSA = true ;
10731087 if (options != null && options .contains (Options .DUMP_SSA_IR )) {
@@ -1098,6 +1112,10 @@ public void recordDef(Operand operand, Instruction instruction) {
10981112 public void sealBlock (BasicBlock block ) {
10991113 }
11001114 @ Override
1115+ public boolean isSealed (BasicBlock block ) {
1116+ return false ;
1117+ }
1118+ @ Override
11011119 public void finish (EnumSet <Options > options ) {
11021120 }
11031121 }
0 commit comments