diff --git a/src/IR.h b/src/IR.h index 535d7e5..74d5a94 100644 --- a/src/IR.h +++ b/src/IR.h @@ -918,6 +918,7 @@ namespace sysy int variableID; int blockID; block_list blocks; + block_list exit_blocks; public: Type *getReturnType() const @@ -935,6 +936,16 @@ namespace sysy blocks.emplace_back(new BasicBlock(this, name)); return blocks.back().get(); } + BasicBlock *addExitBlock(const std::string &name = "") + { + exit_blocks.emplace_back(new BasicBlock(this, name)); + return exit_blocks.back().get(); + } + void moveExitBlock() + { + // move(exit_blocks.back()); + blocks.emplace_back(move(exit_blocks.back())); + } void removeBasicBlock(BasicBlock *block) { blocks.remove_if([&](std::unique_ptr &b) -> bool diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 57fdea4..617195d 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -305,19 +305,21 @@ namespace sysy // create exit basicblock char exitname[20]; sprintf(exitname, "exit%d", builder.get_ifcnt() + builder.get_whilecnt()); - auto exitblock = func->addBasicBlock(exitname); + auto exitblock = func->addExitBlock(exitname); + // auto exitblock = func->addBasicBlock(exitname); exitblock->getPredecessors().push_back(thenblock); thenblock->getSuccessors().push_back(exitblock); builder.push_truetarget(thenblock); builder.push_falsetarget(exitblock); auto cond = any_cast(ctx->exp()->accept(this)); - builder.poptarget(); + func->moveExitBlock(); char flagname[20]; sprintf(flagname, "flag%d", builder.get_ifcnt() + builder.get_whilecnt()); // cond->setName(flagname); current_block->getSuccessors().push_back(exitblock); exitblock->getPredecessors().push_back(current_block); - Value *CondBr = builder.createCondBrInst(cond, thenblock, exitblock, vector(), vector()); + Value *CondBr = builder.createCondBrInst(cond, builder.get_truetarget(), builder.get_falsetarget(), vector(), vector()); + builder.poptarget(); builder.setPosition(thenblock, thenblock->begin()); visitStmt(ctx->stmt()[0]); Value *then_br = builder.createUncondBrInst(exitblock, vector()); @@ -334,7 +336,8 @@ namespace sysy // create exit basicblock char exitname[20]; sprintf(exitname, "exit%d", builder.get_ifcnt() + builder.get_whilecnt()); - auto exitblock = func->addBasicBlock(exitname); + // auto exitblock = func->addBasicBlock(exitname); + auto exitblock = func->addExitBlock(exitname); exitblock->getPredecessors().push_back(thenblock); thenblock->getSuccessors().push_back(exitblock); current_block->getSuccessors().push_back(elseblock); @@ -345,8 +348,9 @@ namespace sysy builder.push_truetarget(thenblock); builder.push_falsetarget(elseblock); auto cond = any_cast(ctx->exp()->accept(this)); + func->moveExitBlock(); + CondBrInst *CondBr = builder.createCondBrInst(cond, builder.get_truetarget(), builder.get_falsetarget(), vector(), vector()); builder.poptarget(); - CondBrInst *CondBr = builder.createCondBrInst(cond, thenblock, elseblock, vector(), vector()); builder.setPosition(thenblock, thenblock->begin()); visitStmt(ctx->stmt()[0]); Value *then_br = builder.createUncondBrInst(exitblock, vector()); @@ -382,7 +386,7 @@ namespace sysy // create exit basicblock char exitname[20]; sprintf(exitname, "exit%d", builder.get_whilecnt() + builder.get_ifcnt()); - auto exitblock = func->addBasicBlock(exitname); + auto exitblock = func->addExitBlock(exitname); headerblock->getSuccessors().push_back(exitblock); exitblock->getPredecessors().push_back(headerblock); // push header&exit into loopstack @@ -392,12 +396,13 @@ namespace sysy builder.push_truetarget(bodyblock); builder.push_falsetarget(exitblock); auto cond = any_cast(ctx->exp()->accept(this)); - builder.poptarget(); + func->moveExitBlock(); // char flagname[20]; // sprintf(flagname, "flag%d", builder.get_ifcnt() + builder.get_whilecnt()); // cond->setName(flagname); // create condbr in header - Value *header_condbr = builder.createCondBrInst(cond, bodyblock, exitblock, vector(), vector()); + Value *header_condbr = builder.createCondBrInst(cond, builder.get_truetarget(), builder.get_falsetarget(), vector(), vector()); + builder.poptarget(); // generate code in body block builder.setPosition(bodyblock, bodyblock->begin()); visitStmt(ctx->stmt()); @@ -423,15 +428,29 @@ namespace sysy any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext *ctx) { // generate the operands - auto hs = any_cast(ctx->exp()->accept(this)); Value *result = nullptr; if (ctx->SUB()) + { + auto hs = any_cast(ctx->exp()->accept(this)); result = builder.createNegInst(hs); + } else if (ctx->NOT()) - result = builder.createNotInst(hs); + // result = builder.createNotInst(hs); + { + auto true_target = builder.get_falsetarget(); + auto false_target = builder.get_truetarget(); + builder.poptarget(); + builder.push_truetarget(true_target); + builder.push_falsetarget(false_target); + auto hs = any_cast(ctx->exp()->accept(this)); + result = hs; + } else if (ctx->ADD()) + { + auto hs = any_cast(ctx->exp()->accept(this)); result = hs; + } return result; }