Ensure that basic blocks in loops and branches are well formed.
This commit is contained in:
parent
ec76d2a21d
commit
cf241951a0
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Reference in New Issue
Block a user