@@ -62,14 +62,13 @@ llvm::Value *Codegen::generateIfStmt(const ResolvedIfStmt &stmt) {
6262 trueBB->insertInto (function);
6363 builder.SetInsertPoint (trueBB);
6464 generateBlock (*stmt.trueBlock );
65- builder. CreateBr (exitBB);
65+ breakIntoBB (exitBB);
6666
6767 if (stmt.falseBlock ) {
6868 elseBB->insertInto (function);
69-
7069 builder.SetInsertPoint (elseBB);
7170 generateBlock (*stmt.falseBlock );
72- builder. CreateBr (exitBB);
71+ breakIntoBB (exitBB);
7372 }
7473
7574 exitBB->insertInto (function);
@@ -92,7 +91,7 @@ llvm::Value *Codegen::generateWhileStmt(const ResolvedWhileStmt &stmt) {
9291
9392 builder.SetInsertPoint (body);
9493 generateBlock (*stmt.body );
95- builder. CreateBr (header);
94+ breakIntoBB (header);
9695
9796 builder.SetInsertPoint (exit);
9897 return nullptr ;
@@ -120,7 +119,8 @@ llvm::Value *Codegen::generateReturnStmt(const ResolvedReturnStmt &stmt) {
120119 storeValue (generateExpr (*stmt.expr ), retVal, stmt.expr ->type );
121120
122121 assert (retBB && " function with return stmt doesn't have a return block" );
123- return builder.CreateBr (retBB);
122+ breakIntoBB (retBB);
123+ return nullptr ;
124124}
125125
126126llvm::Value *Codegen::generateMemberExpr (const ResolvedMemberExpr &memberExpr,
@@ -290,6 +290,9 @@ Codegen::generateBinaryOperator(const ResolvedBinaryOperator &binop) {
290290
291291 builder.SetInsertPoint (rhsBB);
292292 llvm::Value *rhs = doubleToBool (generateExpr (*binop.rhs ));
293+
294+ assert (!builder.GetInsertBlock ()->getTerminator () &&
295+ " a binop terminated the current block" );
293296 builder.CreateBr (mergeBB);
294297
295298 rhsBB = builder.GetInsertBlock ();
@@ -362,6 +365,15 @@ llvm::Value *Codegen::boolToDouble(llvm::Value *v) {
362365 return builder.CreateUIToFP (v, builder.getDoubleTy (), " to.double" );
363366}
364367
368+ void Codegen::breakIntoBB (llvm::BasicBlock *targetBB) {
369+ llvm::BasicBlock *currentBB = builder.GetInsertBlock ();
370+
371+ if (currentBB && !currentBB->getTerminator ())
372+ builder.CreateBr (targetBB);
373+
374+ builder.ClearInsertionPoint ();
375+ }
376+
365377llvm::Function *Codegen::getCurrentFunction () {
366378 return builder.GetInsertBlock ()->getParent ();
367379};
@@ -405,15 +417,10 @@ void Codegen::generateBlock(const ResolvedBlock &block) {
405417 for (auto &&stmt : block.statements ) {
406418 generateStmt (*stmt);
407419
408- // After a return statement we clear the insertion point, so that
409- // no other instructions are inserted into the current block and break.
410- // The break ensures that no other instruction is generated that will be
411- // inserted regardless of there is no insertion point and crash (e.g.:
412- // CreateStore, CreateLoad).
413- if (dynamic_cast <const ResolvedReturnStmt *>(stmt.get ())) {
414- builder.ClearInsertionPoint ();
420+ // We exited the current basic block for some reason, so there is
421+ // no need for generating the remaining instructions.
422+ if (!builder.GetInsertBlock ())
415423 break ;
416- }
417424 }
418425}
419426
@@ -460,7 +467,7 @@ void Codegen::generateFunctionBody(const ResolvedFunctionDecl &functionDecl) {
460467 generateBlock (*functionDecl.body );
461468
462469 if (retBB->hasNPredecessorsOrMore (1 )) {
463- builder. CreateBr (retBB);
470+ breakIntoBB (retBB);
464471 retBB->insertInto (function);
465472 builder.SetInsertPoint (retBB);
466473 }
0 commit comments