void Codegen::linearize(IR::Function *function)
{
- IR::BasicBlock *entryBlock = function->basicBlocks.at(0);
- IR::BasicBlock *exitBlock = function->basicBlocks.at(1);
-
- Q_UNUSED(entryBlock);
+ IR::BasicBlock *exitBlock = function->basicBlocks.last();
+ assert(exitBlock->isTerminated());
+ assert(exitBlock->terminator()->asRet());
QSet<IR::BasicBlock *> V;
V.insert(exitBlock);
for (int i = 0; i < function->basicBlocks.size(); ++i) {
IR::BasicBlock *block = function->basicBlocks.at(i);
- if (block->statements.isEmpty()) {
- if ((i + 1) < function->basicBlocks.size()) {
- IR::BasicBlock *next = function->basicBlocks.at(i + 1);
- block->JUMP(next);
- }
+ if (!block->isTerminated() && (i + 1) < function->basicBlocks.size()) {
+ IR::BasicBlock *next = function->basicBlocks.at(i + 1);
+ block->JUMP(next);
}
}
enterEnvironment(ast);
IR::Function *function = _module->newFunction(name);
IR::BasicBlock *entryBlock = function->newBasicBlock();
- IR::BasicBlock *exitBlock = function->newBasicBlock();
+ IR::BasicBlock *exitBlock = function->newBasicBlock(IR::Function::DontInsertBlock);
IR::BasicBlock *throwBlock = function->newBasicBlock();
IR::BasicBlock *handlersBlock = function->newBasicBlock();
function->hasDirectEval = _env->hasDirectEval;
sourceElements(body);
+ _function->insertBasicBlock(_exitBlock);
+
if (! _block->isTerminated())
_block->JUMP(_exitBlock);
return &*strings.insert(text);
}
-BasicBlock *Function::newBasicBlock()
+BasicBlock *Function::newBasicBlock(BasicBlockInsertMode mode)
{
- return i(new BasicBlock(this));
+ BasicBlock *block = new BasicBlock(this);
+ return mode == InsertBlock ? insertBasicBlock(block) : block;
}
void Function::dump(QTextStream &out, Stmt::Mode mode)
~Function();
- BasicBlock *newBasicBlock();
+ enum BasicBlockInsertMode {
+ InsertBlock,
+ DontInsertBlock
+ };
+
+ BasicBlock *newBasicBlock(BasicBlockInsertMode mode = InsertBlock);
const QString *newString(const QString &text);
void RECEIVE(const QString &name) { formals.append(newString(name)); }
void LOCAL(const QString &name) { locals.append(newString(name)); }
- inline BasicBlock *i(BasicBlock *block) { basicBlocks.append(block); return block; }
+ inline BasicBlock *insertBasicBlock(BasicBlock *block) { basicBlocks.append(block); return block; }
void dump(QTextStream &out, Stmt::Mode mode = Stmt::HIR);