From cf241951a0197ddc1851c4d15b64005809506d06 Mon Sep 17 00:00:00 2001 From: Stefano Sanfilippo Date: Mon, 9 Mar 2015 22:04:10 +0100 Subject: [PATCH] Ensure that basic blocks in loops and branches are well formed. --- BitcodeEmitter.cpp | 47 ++++++++++++++++++++++++++++------------------ BitcodeEmitter.hpp | 3 +++ 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/BitcodeEmitter.cpp b/BitcodeEmitter.cpp index 1eda9f3..d8f548d 100644 --- a/BitcodeEmitter.cpp +++ b/BitcodeEmitter.cpp @@ -263,11 +263,14 @@ bool BitcodeEmitter::emit(Loop const& node) { d->builder.CreateBr(body); d->builder.SetInsertPoint(body); - d->scope.enter(); - for (Statement const& statement: node.getBody()) { - GUARDED(statement.emit(this)); - } - d->scope.leave(); + llvm::BasicBlock *condition = llvm::BasicBlock::Create( + getGlobalContext(), "loopcondition" + ); + + GUARDED(ensureBasicBlock(node.getBody(), condition)); + + father->getBasicBlockList().push_back(condition); + d->builder.SetInsertPoint(condition); GUARDED(node.getCondition().emit(this)); @@ -467,12 +470,8 @@ bool BitcodeEmitter::emit(Branch const& node) { isTrue(d, d->retval, "condition"), thenbb, elsebb ); d->builder.SetInsertPoint(thenbb); - d->scope.enter(); - for (Statement const& statement: cas.getBody()) { - GUARDED(statement.emit(this)); - } - d->scope.leave(); - d->builder.CreateBr(mergebb); + + GUARDED(ensureBasicBlock(cas.getBody(), mergebb)); func->getBasicBlockList().push_back(elsebb); d->builder.SetInsertPoint(elsebb); @@ -484,12 +483,7 @@ bool BitcodeEmitter::emit(Branch const& node) { } if (body.getElse()) { - d->scope.enter(); - for (Statement const& statement: *body.getElse()) { - GUARDED(statement.emit(this)); - } - d->scope.leave(); - d->builder.CreateBr(mergebb); + GUARDED(ensureBasicBlock(*body.getElse(), mergebb)); } func->getBasicBlockList().push_back(mergebb); @@ -590,7 +584,10 @@ bool BitcodeEmitter::emit(Function const& node) { d->scope.leave(); - d->builder.CreateBr(d->funcExit); + if (!d->builder.GetInsertBlock()->getTerminator()) { + d->builder.CreateBr(d->funcExit); + } + func->getBasicBlockList().push_back(d->funcExit); d->builder.SetInsertPoint(d->funcExit); @@ -757,3 +754,17 @@ bool BitcodeEmitter::emitSemiExpression(Id const& left, SemiExpression const& ri return true; } +bool BitcodeEmitter::ensureBasicBlock(PointerList const& statements, llvm::BasicBlock *after) { + d->scope.enter(); + for (Statement const& statement: statements) { + GUARDED(statement.emit(this)); + } + d->scope.leave(); + + if (!d->builder.GetInsertBlock()->getTerminator()) { + d->builder.CreateBr(after); + } + + return true; +} + diff --git a/BitcodeEmitter.hpp b/BitcodeEmitter.hpp index a654db6..2a716a2 100644 --- a/BitcodeEmitter.hpp +++ b/BitcodeEmitter.hpp @@ -27,11 +27,13 @@ namespace llvm { class Module; class Function; + class BasicBlock; } namespace monicelli { class SemiExpression; +class Statement; class BitcodeEmitter: public Emitter { public: @@ -67,6 +69,7 @@ public: private: bool emitSemiExpression(Id const& left, SemiExpression const& right); + bool ensureBasicBlock(PointerList const& statements, llvm::BasicBlock *after); Pointer module; Private *d;