diff --git a/src/IRBuilder.h b/src/IRBuilder.h index 0dd3270..42ddc77 100644 --- a/src/IRBuilder.h +++ b/src/IRBuilder.h @@ -13,13 +13,15 @@ namespace sysy BasicBlock *block; BasicBlock::iterator position; std::stack headers, exits; - int if_cnt, while_cnt; + int if_cnt, while_cnt, rhs_cnt; + std::stack truetargets, falsetargets; public: IRBuilder() { if_cnt = 0; while_cnt = 0; + rhs_cnt = 0; } IRBuilder(BasicBlock *block) : block(block), position(block->end()) { @@ -53,8 +55,19 @@ namespace sysy } void if_add() { if_cnt++; } void while_add() { while_cnt++; } + void rhs_add() { rhs_cnt++; } int get_ifcnt() { return if_cnt; } int get_whilecnt() { return while_cnt; } + int get_rhscnt() { return rhs_cnt; } + void push_truetarget(BasicBlock *truetarget) { truetargets.push(truetarget); } + void push_falsetarget(BasicBlock *falsetarget) { falsetargets.push(falsetarget); } + void poptarget() + { + truetargets.pop(); + falsetargets.pop(); + } + BasicBlock *get_truetarget() { return truetargets.top(); } + BasicBlock *get_falsetarget() { return falsetargets.top(); } public: CallInst *createCallInst(Function *callee, diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 97a09ef..5a966fe 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -259,11 +259,6 @@ namespace sysy any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { builder.if_add(); - // generate condition expression - auto cond = any_cast(ctx->exp()->accept(this)); - char flagname[20]; - sprintf(flagname, "flag%d", builder.get_ifcnt() + builder.get_whilecnt()); - cond->setName(flagname); auto current_block = builder.getBasicBlock(); auto func = current_block->getParent(); // create then basicblock @@ -278,11 +273,20 @@ namespace sysy auto exitblock = func->addBasicBlock(exitname); exitblock->getPredecessors().push_back(thenblock); thenblock->getSuccessors().push_back(exitblock); + // create condbr instr // visit thenblock(and elseblock) if (ctx->stmt().size() == 1) { // if-then + // generate condition expression + builder.push_truetarget(thenblock); + builder.push_falsetarget(exitblock); + auto cond = any_cast(ctx->exp()->accept(this)); + builder.poptarget(); + 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()); @@ -301,6 +305,11 @@ namespace sysy elseblock->getPredecessors().push_back(current_block); elseblock->getSuccessors().push_back(exitblock); exitblock->getPredecessors().push_back(current_block); + // generate condition expression + builder.push_truetarget(thenblock); + builder.push_falsetarget(elseblock); + auto cond = any_cast(ctx->exp()->accept(this)); + builder.poptarget(); CondBrInst *CondBr = builder.createCondBrInst(cond, thenblock, elseblock, vector(), vector()); builder.setPosition(thenblock, thenblock->begin()); visitStmt(ctx->stmt()[0]); @@ -323,16 +332,11 @@ namespace sysy char headername[20]; sprintf(headername, "header%d", builder.get_whilecnt()); auto headerblock = func->addBasicBlock(headername); + builder.setPosition(headerblock, headerblock->begin()); current_block->getSuccessors().push_back(headerblock); headerblock->getPredecessors().push_back(current_block); // uncondbr:current->header // Value *Current_uncondbr = builder.createUncondBrInst(headerblock, vector()); - // generate condition expression - builder.setPosition(headerblock, headerblock->begin()); - auto cond = any_cast(ctx->exp()->accept(this)); - char flagname[20]; - sprintf(flagname, "flag%d", builder.get_ifcnt() + builder.get_whilecnt()); - cond->setName(flagname); // create body basicblock char bodyname[20]; sprintf(bodyname, "body%d", builder.get_whilecnt()); @@ -348,6 +352,14 @@ namespace sysy // push header&exit into loopstack builder.pushheader(headerblock); builder.pushexit(exitblock); + // generate condition expression + builder.push_truetarget(bodyblock); + builder.push_falsetarget(exitblock); + auto cond = any_cast(ctx->exp()->accept(this)); + builder.poptarget(); + 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()); // generate code in body block @@ -441,4 +453,43 @@ namespace sysy return result; } //******************Revised by lyq END*************************************** + + any SysYIRGenerator::visitAndExp(SysYParser::AndExpContext *ctx) + { + // get lhs value + auto lhs = any_cast(ctx->exp()[0]->accept(this)); + // create rhs block + builder.rhs_add(); + auto current_block = builder.getBasicBlock(); + auto func = current_block->getParent(); + char rhs_name[20]; + sprintf(rhs_name, "rhs%d", builder.get_rhscnt()); + auto rhs_block = func->addBasicBlock(rhs_name); + rhs_block->getPredecessors().push_back(current_block); + current_block->getSuccessors().push_back(rhs_block); + // create condbr instr + Value *condbr = builder.createCondBrInst(lhs, rhs_block, builder.get_falsetarget(), vector(), vector()); + // generate code for rhs block + builder.setPosition(rhs_block, rhs_block->begin()); + return (ctx->exp()[1]->accept(this)); + } + any SysYIRGenerator::visitOrExp(SysYParser::OrExpContext *ctx) + { + // get lhs value + auto lhs = any_cast(ctx->exp()[0]->accept(this)); + // create rhs block + builder.rhs_add(); + auto current_block = builder.getBasicBlock(); + auto func = current_block->getParent(); + char rhs_name[20]; + sprintf(rhs_name, "rhs%d", builder.get_rhscnt()); + auto rhs_block = func->addBasicBlock(rhs_name); + rhs_block->getPredecessors().push_back(current_block); + current_block->getSuccessors().push_back(rhs_block); + // create condbr instr + Value *condbr = builder.createCondBrInst(lhs, builder.get_truetarget(), rhs_block, vector(), vector()); + // generate code for rhs block + builder.setPosition(rhs_block, rhs_block->begin()); + return (ctx->exp()[1]->accept(this)); + } } // namespace sysy diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index d4f992a..da1b416 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -176,10 +176,7 @@ namespace sysy virtual std::any visitNumberExp(SysYParser::NumberExpContext *ctx) override; - virtual std::any visitAndExp(SysYParser::AndExpContext *ctx) override - { - return visitChildren(ctx); - } + virtual std::any visitAndExp(SysYParser::AndExpContext *ctx) override; virtual std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override; @@ -193,10 +190,7 @@ namespace sysy return visitChildren(ctx); } - virtual std::any visitOrExp(SysYParser::OrExpContext *ctx) override - { - return visitChildren(ctx); - } + virtual std::any visitOrExp(SysYParser::OrExpContext *ctx) override; virtual std::any visitCallExp(SysYParser::CallExpContext *ctx) override {