【仓库更新】增加对if,while语句的翻译

main
wqz 3 years ago
parent 2265912985
commit 90e9e0e7fb

@ -724,7 +724,7 @@ namespace sysy
protected:
UncondBrInst(BasicBlock *block, std::vector<Value *> args,
BasicBlock *parent = nullptr)
: Instruction(kCondBr, Type::getVoidType(), parent, "")
: Instruction(kBr, Type::getVoidType(), parent, "")
{
assert(block->getNumArguments() == args.size());
addOperand(block);
@ -901,7 +901,7 @@ namespace sysy
Function(Module *parent, Type *type, const std::string &name)
: Value(kFunction, type, name), parent(parent), variableID(0), blocks()
{
blocks.emplace_back(new BasicBlock(this, "entry"));
// blocks.emplace_back(new BasicBlock(this, "entry"));
}
public:

@ -13,7 +13,7 @@ namespace sysy
BasicBlock *block;
BasicBlock::iterator position;
std::stack<BasicBlock *> headers, exits;
int if_cnt, while_cnt, rhs_cnt;
int if_cnt, while_cnt, rhs_cnt, func_cnt;
std::stack<BasicBlock *> truetargets, falsetargets;
public:
@ -22,17 +22,20 @@ namespace sysy
if_cnt = 0;
while_cnt = 0;
rhs_cnt = 0;
func_cnt = 0;
}
IRBuilder(BasicBlock *block) : block(block), position(block->end())
{
if_cnt = 0;
while_cnt = 0;
func_cnt = 0;
}
IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: block(block), position(position)
{
if_cnt = 0;
while_cnt = 0;
func_cnt = 0;
}
public:
@ -56,9 +59,11 @@ namespace sysy
void if_add() { if_cnt++; }
void while_add() { while_cnt++; }
void rhs_add() { rhs_cnt++; }
void func_add() { func_cnt++; }
int get_ifcnt() { return if_cnt; }
int get_whilecnt() { return while_cnt; }
int get_rhscnt() { return rhs_cnt; }
int get_funccnt() { return func_cnt; }
void push_truetarget(BasicBlock *truetarget) { truetargets.push(truetarget); }
void push_falsetarget(BasicBlock *falsetarget) { falsetargets.push(falsetarget); }
void poptarget()

@ -18,14 +18,14 @@ namespace sysy
auto pModule = new Module();
assert(pModule);
module.reset(pModule);
// create function:getint
auto getint_type = Type::getFunctionType(Type::getIntType());
auto f_getint = pModule->createFunction("getint", getint_type);
symbols.insert("getint", f_getint);
// create function:putint
auto putint_type = Type::getFunctionType(Type::getVoidType(), vector<Type *>({Type::getIntType()}));
auto f_putint = pModule->createFunction("putint", putint_type);
symbols.insert("putint", f_putint);
// // create function:getint
// auto getint_type = Type::getFunctionType(Type::getIntType());
// auto f_getint = pModule->createFunction("getint", getint_type);
// symbols.insert("getint", f_getint);
// // create function:putint
// auto putint_type = Type::getFunctionType(Type::getVoidType(), vector<Type *>({Type::getIntType()}));
// auto f_putint = pModule->createFunction("putint", putint_type);
// symbols.insert("putint", f_putint);
// generates globals and functions
visitChildren(ctx);
// return the IR module
@ -93,6 +93,7 @@ namespace sysy
any SysYIRGenerator::visitFunc(SysYParser::FuncContext *ctx)
{
// obtain function name and type signature
builder.func_add();
auto name = ctx->ID()->getText();
vector<Type *> paramTypes;
vector<string> paramNames;
@ -109,13 +110,16 @@ namespace sysy
auto funcType = Type::getFunctionType(returnType, paramTypes);
// create the IR function
auto function = module->createFunction(name, funcType);
char entry_name[10];
sprintf(entry_name, "entry%d", builder.get_funccnt());
// update the symbol table
symbols.insert(name, function);
// create the function scope
SymbolTable::FunctionScope scope(symbols);
// create the entry block with the same parameters as the function,
// and update the symbol table
auto entry = function->getEntryBlock();
auto entry = function->addBasicBlock(entry_name);
// auto entry = function->getEntryBlock();
for (auto i = 0; i < paramTypes.size(); ++i)
{
auto arg = entry->createArgument(paramTypes[i], paramNames[i]);
@ -292,32 +296,33 @@ namespace sysy
auto thenblock = func->addBasicBlock(thenname);
current_block->getSuccessors().push_back(thenblock);
thenblock->getPredecessors().push_back(current_block);
// create exit basicblock
char exitname[20];
sprintf(exitname, "exit%d", builder.get_ifcnt() + builder.get_whilecnt());
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
// create exit basicblock
char exitname[20];
sprintf(exitname, "exit%d", builder.get_ifcnt() + builder.get_whilecnt());
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<Value *>(ctx->exp()->accept(this));
builder.poptarget();
char flagname[20];
sprintf(flagname, "flag%d", builder.get_ifcnt() + builder.get_whilecnt());
cond->setName(flagname);
// cond->setName(flagname);
current_block->getSuccessors().push_back(exitblock);
exitblock->getPredecessors().push_back(current_block);
Value *CondBr = builder.createCondBrInst(cond, thenblock, exitblock, vector<Value *>(), vector<Value *>());
builder.setPosition(thenblock, thenblock->begin());
visitStmt(ctx->stmt()[0]);
Value *then_br = builder.createUncondBrInst(exitblock, vector<Value *>());
// setup the instruction insert position
builder.setPosition(exitblock, exitblock->begin());
}
if (ctx->stmt().size() == 2)
{
@ -326,6 +331,12 @@ namespace sysy
char elsename[20];
sprintf(elsename, "else%d", builder.get_ifcnt());
auto elseblock = func->addBasicBlock(elsename);
// create exit basicblock
char exitname[20];
sprintf(exitname, "exit%d", builder.get_ifcnt() + builder.get_whilecnt());
auto exitblock = func->addBasicBlock(exitname);
exitblock->getPredecessors().push_back(thenblock);
thenblock->getSuccessors().push_back(exitblock);
current_block->getSuccessors().push_back(elseblock);
elseblock->getPredecessors().push_back(current_block);
elseblock->getSuccessors().push_back(exitblock);
@ -342,9 +353,9 @@ namespace sysy
builder.setPosition(elseblock, elseblock->begin());
visitStmt(ctx->stmt()[1]);
Value *else_br = builder.createUncondBrInst(exitblock, vector<Value *>());
// setup the instruction insert position
builder.setPosition(exitblock, exitblock->begin());
}
// setup the instruction insert position
builder.setPosition(exitblock, exitblock->begin());
return builder.getBasicBlock();
}
@ -382,9 +393,9 @@ namespace sysy
builder.push_falsetarget(exitblock);
auto cond = any_cast<Value *>(ctx->exp()->accept(this));
builder.poptarget();
char flagname[20];
sprintf(flagname, "flag%d", builder.get_ifcnt() + builder.get_whilecnt());
cond->setName(flagname);
// 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<Value *>(), vector<Value *>());
// generate code in body block

@ -219,8 +219,8 @@ namespace backend
string CodeGen::basicBlock_gen(BasicBlock *bb)
{
curBB = bb;
// string bbLabel = bb->getName();
string bbLabel = getBBLabel(bb);
string bbLabel = bb->getName();
// string bbLabel = getBBLabel(bb);
string code;
code += bbLabel + ":" + endl;
for (auto &instr : bb->getInstructions())
@ -244,11 +244,15 @@ namespace backend
auto lhs = bInst->getLhs();
if (isa<ConstantValue>(lhs))
lname = "#" + to_string(dynamic_cast<ConstantValue *>(lhs)->getInt());
else if (isa<CallInst>(lhs))
lname = "r0";
else
lname = "r" + lhs->getName();
auto rhs = bInst->getRhs();
if (isa<ConstantValue>(rhs))
rname = "#" + to_string(dynamic_cast<ConstantValue *>(rhs)->getInt());
else if (isa<CallInst>(lhs))
lname = "r0";
else
rname = "r" + rhs->getName();
auto res = stoi(bInst->getName());
@ -260,6 +264,18 @@ namespace backend
code += space + "mul\tr" + to_string(res) + ", " + lname + ", " + rname + endl;
else if (bInst->getKind() == Instruction::kDiv)
code += space + "div\tr" + to_string(res) + ", " + lname + ", " + rname + endl;
else if (bInst->getKind() == Instruction::kICmpEQ)
code += space + "cmp\t" + lname + ", " + rname + endl;
else if (bInst->getKind() == Instruction::kICmpGE)
code += space + "cmp\t" + lname + ", " + rname + endl;
else if (bInst->getKind() == Instruction::kICmpGT)
code += space + "cmp\t" + lname + ", " + rname + endl;
else if (bInst->getKind() == Instruction::kICmpLE)
code += space + "cmp\t" + lname + ", " + rname + endl;
else if (bInst->getKind() == Instruction::kICmpLT)
code += space + "cmp\t" + lname + ", " + rname + endl;
else if (bInst->getKind() == Instruction::kICmpNE)
code += space + "cmp\t" + lname + ", " + rname + endl;
return {dstRegId, code};
}
@ -338,17 +354,6 @@ namespace backend
code += space + "ldr\tr" + to_string(reg_num) + ", [fp, #unk]" + endl;
backpatch.push_back(dynamic_cast<Argument *>(var));
}
// {
// code += "load var in paramvar\n";
// for (auto arg : paramsStOffset)
// {
// if (arg.first == var)
// {
// // pos = arg.second;
// break;
// }
// }
// }
return {dstRegId, code};
}
string CodeGen::returnInst_gen(ReturnInst *retInst)
@ -374,6 +379,8 @@ namespace backend
/**
*code in here
*/
auto goal = ubInst->getBlock();
code += space + "b\t" + goal->getName() + endl;
return code;
}
string CodeGen::condBrInst_gen(CondBrInst *cbInst)
@ -382,6 +389,51 @@ namespace backend
/**
*code in here
*/
auto cond = cbInst->getCondition();
auto then_block = cbInst->getThenBlock();
auto else_block = cbInst->getElseBlock();
if (cond->getKind())
{
BinaryInst *bInst = dynamic_cast<BinaryInst *>(cond);
// auto lhs = bInst->getLhs();
// auto rhs = bInst->getRhs();
if (bInst->getKind() == Instruction::kICmpEQ)
{
// code += binaryInst_gen(bInst, RegManager::RANY).second;
code += space + "beq\t" + then_block->getName() + endl;
code += space + "b\t" + else_block->getName() + endl;
}
else if (bInst->getKind() == Instruction::kICmpGE)
{
// code += binaryInst_gen(bInst, RegManager::RANY).second;
code += space + "bge\t" + then_block->getName() + endl;
code += space + "b\t" + else_block->getName() + endl;
}
else if (bInst->getKind() == Instruction::kICmpGT)
{
// code += binaryInst_gen(bInst, RegManager::RANY).second;
code += space + "bgt\t" + then_block->getName() + endl;
code += space + "b\t" + else_block->getName() + endl;
}
else if (bInst->getKind() == Instruction::kICmpLE)
{
// code += binaryInst_gen(bInst, RegManager::RANY).second;
code += space + "ble\t" + then_block->getName() + endl;
code += space + "b\t" + else_block->getName() + endl;
}
else if (bInst->getKind() == Instruction::kICmpLT)
{
// code += binaryInst_gen(bInst, RegManager::RANY).second;
code += space + "blt\t" + then_block->getName() + endl;
code += space + "b\t" + else_block->getName() + endl;
}
else if (bInst->getKind() == Instruction::kICmpNE)
{
// code += binaryInst_gen(bInst, RegManager::RANY).second;
code += space + "bne\t" + then_block->getName() + endl;
code += space + "b\t" + else_block->getName() + endl;
}
}
return code;
}
pair<RegId, string>
@ -427,9 +479,16 @@ namespace backend
switch (instrType)
{
// binary inst
case Instruction::kICmpEQ:
case Instruction::kICmpGE:
case Instruction::kICmpGT:
case Instruction::kICmpLE:
case Instruction::kICmpLT:
case Instruction::kICmpNE:
case Instruction::kAdd:
case Instruction::kMul:
case Instruction::kSub:
case Instruction::kDiv:
{
BinaryInst *bInst = dynamic_cast<BinaryInst *>(instr);
// registers are used only for instruction operation, consider use which register (any one that is free for use)

Loading…
Cancel
Save