Ensure that basic blocks in loops and branches are well formed.

This commit is contained in:
Stefano Sanfilippo 2015-03-09 22:04:10 +01:00
parent ec76d2a21d
commit cf241951a0
2 changed files with 32 additions and 18 deletions

View File

@ -263,11 +263,14 @@ bool BitcodeEmitter::emit(Loop const& node) {
d->builder.CreateBr(body); d->builder.CreateBr(body);
d->builder.SetInsertPoint(body); d->builder.SetInsertPoint(body);
d->scope.enter(); llvm::BasicBlock *condition = llvm::BasicBlock::Create(
for (Statement const& statement: node.getBody()) { getGlobalContext(), "loopcondition"
GUARDED(statement.emit(this)); );
}
d->scope.leave(); GUARDED(ensureBasicBlock(node.getBody(), condition));
father->getBasicBlockList().push_back(condition);
d->builder.SetInsertPoint(condition);
GUARDED(node.getCondition().emit(this)); GUARDED(node.getCondition().emit(this));
@ -467,12 +470,8 @@ bool BitcodeEmitter::emit(Branch const& node) {
isTrue(d, d->retval, "condition"), thenbb, elsebb isTrue(d, d->retval, "condition"), thenbb, elsebb
); );
d->builder.SetInsertPoint(thenbb); d->builder.SetInsertPoint(thenbb);
d->scope.enter();
for (Statement const& statement: cas.getBody()) { GUARDED(ensureBasicBlock(cas.getBody(), mergebb));
GUARDED(statement.emit(this));
}
d->scope.leave();
d->builder.CreateBr(mergebb);
func->getBasicBlockList().push_back(elsebb); func->getBasicBlockList().push_back(elsebb);
d->builder.SetInsertPoint(elsebb); d->builder.SetInsertPoint(elsebb);
@ -484,12 +483,7 @@ bool BitcodeEmitter::emit(Branch const& node) {
} }
if (body.getElse()) { if (body.getElse()) {
d->scope.enter(); GUARDED(ensureBasicBlock(*body.getElse(), mergebb));
for (Statement const& statement: *body.getElse()) {
GUARDED(statement.emit(this));
}
d->scope.leave();
d->builder.CreateBr(mergebb);
} }
func->getBasicBlockList().push_back(mergebb); func->getBasicBlockList().push_back(mergebb);
@ -590,7 +584,10 @@ bool BitcodeEmitter::emit(Function const& node) {
d->scope.leave(); d->scope.leave();
d->builder.CreateBr(d->funcExit); if (!d->builder.GetInsertBlock()->getTerminator()) {
d->builder.CreateBr(d->funcExit);
}
func->getBasicBlockList().push_back(d->funcExit); func->getBasicBlockList().push_back(d->funcExit);
d->builder.SetInsertPoint(d->funcExit); d->builder.SetInsertPoint(d->funcExit);
@ -757,3 +754,17 @@ bool BitcodeEmitter::emitSemiExpression(Id const& left, SemiExpression const& ri
return true; return true;
} }
bool BitcodeEmitter::ensureBasicBlock(PointerList<Statement> 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;
}

View File

@ -27,11 +27,13 @@
namespace llvm { namespace llvm {
class Module; class Module;
class Function; class Function;
class BasicBlock;
} }
namespace monicelli { namespace monicelli {
class SemiExpression; class SemiExpression;
class Statement;
class BitcodeEmitter: public Emitter { class BitcodeEmitter: public Emitter {
public: public:
@ -67,6 +69,7 @@ public:
private: private:
bool emitSemiExpression(Id const& left, SemiExpression const& right); bool emitSemiExpression(Id const& left, SemiExpression const& right);
bool ensureBasicBlock(PointerList<Statement> const& statements, llvm::BasicBlock *after);
Pointer<llvm::Module> module; Pointer<llvm::Module> module;
Private *d; Private *d;