// SysYIRGenerator.cpp // TODO:类型转换及其检查 // TODO:sysy库函数处理 // TODO:数组处理 // TODO:对while、continue、break的测试 #include "IR.h" #include #include using namespace std; #include "SysYIRGenerator.h" namespace sysy { /* * @brief: visit compUnit * @details: * compUnit: (decl | funcDef)+; */ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) { // create the IR module auto pModule = new Module(); assert(pModule); module.reset(pModule); SymbolTable::ModuleScope scope(symbols_table); // 待添加运行时库函数getint等 // generates globals and functions auto type_i32 = Type::getIntType(); auto type_f32 = Type::getFloatType(); auto type_void = Type::getVoidType(); auto type_i32p = Type::getPointerType(type_i32); auto type_f32p = Type::getPointerType(type_f32); //runtime library module->createFunction("getint", Type::getFunctionType(type_i32, {})); module->createFunction("getch", Type::getFunctionType(type_i32, {})); module->createFunction("getfloat", Type::getFunctionType(type_f32, {})); symbols_table.insert("getint", module->getFunction("getint")); symbols_table.insert("getch", module->getFunction("getch")); symbols_table.insert("getfloat", module->getFunction("getfloat")); module->createFunction("getarray", Type::getFunctionType(type_i32, {type_i32p})); module->createFunction("getfarray", Type::getFunctionType(type_i32, {type_f32p})); symbols_table.insert("getarray", module->getFunction("getarray")); symbols_table.insert("getfarray", module->getFunction("getfarray")); module->createFunction("putint", Type::getFunctionType(type_void, {type_i32})); module->createFunction("putch", Type::getFunctionType(type_void, {type_i32})); module->createFunction("putfloat", Type::getFunctionType(type_void, {type_f32})); symbols_table.insert("putint", module->getFunction("putint")); symbols_table.insert("putch", module->getFunction("putch")); symbols_table.insert("putfloat", module->getFunction("putfloat")); module->createFunction("putarray", Type::getFunctionType(type_void, {type_i32, type_i32p})); module->createFunction("putfarray", Type::getFunctionType(type_void, {type_i32, type_f32p})); symbols_table.insert("putarray", module->getFunction("putarray")); symbols_table.insert("putfarray", module->getFunction("putfarray")); module->createFunction("putf", Type::getFunctionType(type_void, {})); symbols_table.insert("putf", module->getFunction("putf")); module->createFunction("starttime", Type::getFunctionType(type_void, {type_i32})); module->createFunction("stoptime", Type::getFunctionType(type_void, {type_i32})); symbols_table.insert("starttime", module->getFunction("starttime")); symbols_table.insert("stoptime", module->getFunction("stoptime")); // visit all decls and funcDefs for(auto decl:ctx->decl()){ decl->accept(this); } for(auto funcDef:ctx->funcDef()){ builder = IRBuilder(); printf("entry funcDef\n"); funcDef->accept(this); } // return the IR module ? return pModule; } /* * @brief: visit decl * @details: * decl: constDecl | varDecl; * constDecl: CONST bType constDef (COMMA constDef)* SEMI; * varDecl: bType varDef (COMMA varDef)* SEMI; * constDecl and varDecl shares similar syntax structure * we consider them together? not sure */ std::any SysYIRGenerator::visitDecl(SysYParser::DeclContext *ctx) { if(ctx->constDecl()) return visitConstDecl(ctx->constDecl()); else if(ctx->varDecl()) return visitVarDecl(ctx->varDecl()); std::cerr << "error unkown decl" << ctx->getText() << std::endl; return std::any(); } /* * @brief: visit constdecl * @details: * constDecl: CONST bType constDef (COMMA constDef)* SEMI; * constDef: Ident (LBRACK constExp RBRACK)* (ASSIGN constInitVal)?; */ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx) { cout << "visitconstDecl" << endl; current_type = any_cast(ctx->bType()->accept(this)); for(auto constDef:ctx->constDef()){ constDef->accept(this); } return std::any(); } /* * @brief: visit btype * @details: * bType: INT | FLOAT; */ std::any SysYIRGenerator::visitBType(SysYParser::BTypeContext *ctx) { if(ctx->INT()) return Type::getPointerType(Type::getIntType()); else if(ctx->FLOAT()) return Type::getPointerType(Type::getFloatType()); std::cerr << "error: unknown type" << ctx->getText() << std::endl; return std::any(); } /* * @brief: visit constDef * @details: * constDef: Ident (LBRACK constExp RBRACK)* (ASSIGN constInitVal)?; * constInitVal: constExp | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE; */ std::any SysYIRGenerator::visitConstDef(SysYParser::ConstDefContext *ctx){ auto name = ctx->Ident()->getText(); Type* type = current_type; Value* init = ctx->constInitVal() ? any_cast(ctx->constInitVal()->accept(this)) : (Value *)nullptr; if (ctx->constExp().empty()){ //scalar if(init){ if(symbols_table.isModuleScope()){ assert(init->isConstant() && "global must be initialized by constant"); Value* global = module->createGlobalValue(name, type, {}, init); symbols_table.insert(name, global); cout << "add module const " << name ; if(init){ cout << " inited by " ; init->print(cout); } cout << '\n'; } else{ Value* alloca = builder.createAllocaInst(type, {}, name); Value* store = builder.createStoreInst(init, alloca); symbols_table.insert(name, alloca); cout << "add local const " << name ; if(init){ cout << " inited by " ; init->print(cout); } cout << '\n'; } } else{ assert(false && "const without initialization"); } } else{ //array std::cerr << "array constDef not implemented yet" << std::endl; } printf("visitConstDef %s\n",name.c_str()); return std::any(); } /* * @brief: visit constInitVal * @details: * constInitVal: constExp * | LBRACE (constInitVal (COMMA constInitVal)*)? RBRACE; */ std::any SysYIRGenerator::visitConstInitVal(SysYParser::ConstInitValContext *ctx){ Value* initvalue; if(ctx->constExp()) initvalue = any_cast(ctx->constExp()->accept(this)); else{ //还未实现数组初始化等功能待验证 std::cerr << "array initvalue not implemented yet" << std::endl; // auto numConstInitVals = ctx->constInitVal().size(); // vector initvalues; // for(int i = 0; i < numConstInitVals; i++) // initvalues.push_back(any_cast(ctx->constInitVal(i)->accept(this))); // initvalue = ConstantValue::getArray(initvalues); } return initvalue; } /* * @brief: visit function type * @details: * funcType: VOID | INT | FLOAT; */ std::any SysYIRGenerator::visitFuncType(SysYParser::FuncTypeContext* ctx){ if(ctx->INT()) return Type::getIntType(); else if(ctx->FLOAT()) return Type::getFloatType(); else if(ctx->VOID()) return Type::getVoidType(); std::cerr << "invalid function type: " << ctx->getText() << std::endl; return std::any(); } /* * @brief: visit function define * @details: * funcDef: funcType Ident LPAREN funcFParams? RPAREN blockStmt; * funcFParams: funcFParam (COMMA funcFParam)*; * funcFParam: bType Ident (LBRACK RBRACK (LBRACK exp RBRACK)*)?; * entry -> next -> others -> exit * entry: allocas, br * next: retval, params, br * other: blockStmt init block * exit: load retval, ret */ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx){ auto funcName = ctx->Ident()->getText(); auto returnType = any_cast(ctx->funcType()->accept(this)); auto func = module->getFunction(funcName); cout << "func: "; returnType->print(cout); cout << ' '<< funcName.c_str() << endl; vector paramTypes; vector paramNames; if(ctx->funcFParams()){ for(auto funcParam:ctx->funcFParams()->funcFParam()){ Type* paramType = any_cast(funcParam->bType()->accept(this)); paramTypes.push_back(paramType); paramNames.push_back(funcParam->Ident()->getText()); } } auto funcType = FunctionType::get(returnType, paramTypes); auto function = module->createFunction(funcName, funcType); SymbolTable::FunctionScope scope(symbols_table); BasicBlock* entryblock = function->getEntryBlock(); for(size_t i = 0; i < paramTypes.size(); i++) entryblock->createArgument(paramTypes[i], paramNames[i]); for(auto& arg: entryblock->getArguments()) symbols_table.insert(arg->getName(), (Value *)arg.get()); cout << "setposition entryblock" << endl; builder.setPosition(entryblock, entryblock->end()); ctx->blockStmt()->accept(this); return std::any(); } /* * @brief: visit varDecl * @details: * varDecl: bType varDef (COMMA varDef)* SEMI; */ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx){ cout << "visitVarDecl" << endl; current_type = any_cast(ctx->bType()->accept(this)); for(auto varDef:ctx->varDef()){ varDef->accept(this); } return std::any(); } /* * @brief: visit varDef * @details: * varDef: Ident (LBRACK constExp RBRACK)* (ASSIGN initVal)?; */ std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext *ctx){ const std::string name = ctx->Ident()->getText(); Type* type = current_type; Value* init = ctx->initVal() ? any_cast(ctx->initVal()->accept(this)) : nullptr; // const std::vector dims = {}; cout << "vardef: "; current_type->print(cout); cout << ' ' << name << endl; if(ctx->constExp().empty()){ //scalar if(symbols_table.isModuleScope()){ if(init) assert(init->isConstant() && "global must be initialized by constant"); Value* global = module->createGlobalValue(name, type, {}, init); symbols_table.insert(name, global); cout << "add module var " << name ; // if(init){ // cout << " inited by " ; // init->print(cout); // } cout << '\n'; } else{ Value* alloca = builder.createAllocaInst(type, {}, name); cout << "creatalloca" << endl; alloca->print(cout); Value* store = (StoreInst *)nullptr; if(init != nullptr) store = builder.createStoreInst(alloca, init, {}, name); symbols_table.insert(name, alloca); // alloca->setName(name); cout << "add local var " ; alloca->print(cout); // if(init){ // cout << " inited by " ; // init->print(cout); // } cout << '\n'; } } else{ //array std::cerr << "array varDef not implemented yet" << std::endl; } return std::any(); } /* * @brief: visit initVal * @details: * initVal: exp | LBRACE (initVal (COMMA initVal)*)? RBRACE; */ std::any SysYIRGenerator::visitInitVal(SysYParser::InitValContext *ctx) { Value* initvalue = nullptr; if(ctx->exp()) initvalue = any_cast(ctx->exp()->accept(this)); else{ //还未实现数组初始化等功能待验证 std::cerr << "array initvalue not implemented yet" << std::endl; // auto numConstInitVals = ctx->constInitVal().size(); // vector initvalues; // for(int i = 0; i < numConstInitVals; i++) // initvalues.push_back(any_cast(ctx->constInitVal(i)->accept(this))); // initvalue = ConstantValue::getArray(initvalues); } return initvalue; } // std::any SysYIRGenerator::visitFuncFParams(SysYParser::FuncFParamsContext* ctx){ // return visitChildren(ctx); // } // std::any SysYIRGenerator::visitFuncFParam(SysYParser::FuncFParamContext *ctx) { // return visitChildren(ctx); // } /* * @brief: visit blockStmt * @details: * blockStmt: LBRACE blockItem* RBRACE; * blockItem: decl | stmt; */ std::any SysYIRGenerator::visitBlockStmt(SysYParser::BlockStmtContext* ctx){ SymbolTable::BlockScope scope(symbols_table); for (auto item : ctx->blockItem()){ item->accept(this); // if(builder.getBasicBlock()->isTerminal()){ // break; // } } return std::any(); } /* * @brief: visit ifstmt * @details: * ifStmt: IF LPAREN cond RPAREN stmt (ELSE stmt)?; */ std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) { auto condition = any_cast(ctx->cond()->accept(this)); auto thenBlock = builder.getBasicBlock()->getParent()->addBasicBlock("then"); auto elseBlock = builder.getBasicBlock()->getParent()->addBasicBlock("else"); auto condbr = builder.createCondBrInst(condition,thenBlock,elseBlock,{},{}); builder.setPosition(thenBlock, thenBlock->end()); ctx->stmt(0)->accept(this); if(ctx->ELSE()){ builder.setPosition(elseBlock, elseBlock->end()); ctx->stmt(1)->accept(this); } //无条件跳转到下一个基本块 // builder.createUncondBrInst(builder.getBasicBlock()->getParent()->addBasicBlock("next"),{}); return std::any(); } /* * @brief: visit whilestmt * @details: * whileStmt: WHILE LPAREN cond RPAREN stmt; */ std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext* ctx) { //需要解决一个函数多个循环的命名问题 auto header = builder.getBasicBlock()->getParent()->addBasicBlock("header"); auto body = builder.getBasicBlock()->getParent()->addBasicBlock("body"); auto exit = builder.getBasicBlock()->getParent()->addBasicBlock("exit"); SymbolTable::BlockScope scope(symbols_table); { // visit header block builder.setPosition(header, header->end()); auto cond = any_cast(ctx->cond()->accept(this)); auto condbr = builder.createCondBrInst(cond, body, exit, {}, {}); } { // visit body block builder.setPosition(body, body->end()); ctx->stmt()->accept(this); auto uncondbr = builder.createUncondBrInst(header, {}); } // visit exit block builder.setPosition(exit, exit->end()); //无条件跳转到下一个基本块以及一些参数传递 return std::any(); } /* * @brief: visit breakstmt * @details: * breakStmt: BREAK SEMICOLON; */ std::any SysYIRGenerator::visitBreakStmt(SysYParser::BreakStmtContext* ctx) { //如何获取break所在body对应的header块 return std::any(); } /* * @brief Visit ReturnStmt * returnStmt: RETURN exp? SEMICOLON; */ std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) { cout << "visitReturnStmt" << endl; // auto value = ctx->exp() ? any_cast_Value(visit(ctx->exp())) : nullptr; Value* value = ctx->exp() ? any_cast(ctx->exp()->accept(this)) : nullptr; const auto func = builder.getBasicBlock()->getParent(); assert(func && "ret stmt block parent err!"); // 匹配 返回值类型 与 函数定义类型 if (func->getReturnType()->isVoid()) { if (ctx->exp()) assert(false && "the returned value is not matching the function"); auto ret = builder.createReturnInst(); return std::any(); } assert(ctx->exp() && "the returned value is not matching the function"); auto ret = builder.createReturnInst(value); //需要增加无条件跳转吗 return std::any(); } /* * @brief: visit continuestmt * @details: * continueStmt: CONTINUE SEMICOLON; */ std::any SysYIRGenerator::visitContinueStmt(SysYParser::ContinueStmtContext* ctx) { //如何获取continue所在body对应的header块 return std::any(); } /* * @brief visit assign stmt * @details: * assignStmt: lValue ASSIGN exp SEMICOLON */ std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext* ctx) { cout << "visitassignstme :\n"; auto lvalue = any_cast(ctx->lValue()->accept(this)); cout << "getlval" << endl;//lvalue->print(cout);cout << ')'; auto rvalue = any_cast(ctx->exp()->accept(this)); //可能要考虑类型转换例如int a = 1.0 cout << "getrval" << endl;//rvalue->print(cout);cout << ")\n"; builder.createStoreInst(rvalue, lvalue, {}, {}); return std::any(); } /* * @brief: visit lValue * @details: * lValue: Ident (LBRACK exp RBRACK)*; */ std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext* ctx) { cout << "visitLValue" << endl; auto name = ctx->Ident()->getText(); Value* value = symbols_table.lookup(name); assert(value && "lvalue not found"); if(ctx->exp().size() == 0){ //scalar cout << "lvalue: " << name << endl; return value; } else{ //array std::cerr << "array lvalue not implemented yet" << std::endl; } std::cerr << "error lvalue" << ctx->getText() << std::endl; return std::any(); } std::any SysYIRGenerator::visitPrimExp(SysYParser::PrimExpContext *ctx){ cout << "visitPrimExp" << endl; return visitChildren(ctx); } // std::any SysYIRGenerator::visitExp(SysYParser::ExpContext* ctx) { // cout << "visitExp" << endl; // return ctx->addExp()->accept(this); // } std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) { cout << "visitNumber" << endl; Value* res = nullptr; if (auto iLiteral = ctx->ILITERAL()) { /* 基数 (8, 10, 16) */ const auto text = iLiteral->getText(); int base = 10; if (text.find("0x") == 0 || text.find("0X") == 0) { base = 16; } else if (text.find("0b") == 0 || text.find("0B") == 0) { base = 2; } else if (text.find("0") == 0) { base = 8; } res = ConstantValue::get((int)std::stol(text, 0, base)); } else if (auto fLiteral = ctx->FLITERAL()) { const auto text = fLiteral->getText(); res = ConstantValue::get((float)std::stof(text)); } cout << "number: "; res->print(cout); cout << endl; return res; } /* * @brief: visit call * @details: * call: Ident LPAREN funcRParams? RPAREN; */ std::any SysYIRGenerator::visitCall(SysYParser::CallContext* ctx) { cout << "visitCall" << endl; auto funcName = ctx->Ident()->getText(); auto func = module->getFunction(funcName); assert(func && "function not found"); //需要做类型检查和转换 std::vector args; if(ctx->funcRParams()){ for(auto exp:ctx->funcRParams()->exp()){ args.push_back(any_cast(exp->accept(this))); } } Value* call = builder.createCallInst(func, args); return call; } /* * @brief: visit unexp * @details: * unExp: unaryOp unaryExp */ std::any SysYIRGenerator::visitUnExp(SysYParser::UnExpContext *ctx) { cout << "visitUnExp" << endl; Value* res = nullptr; auto op = ctx->unaryOp()->getText(); auto exp = any_cast(ctx->unaryExp()->accept(this)); if(ctx->unaryOp()->ADD()){ res = exp; } else if(ctx->unaryOp()->SUB()){ res = builder.createNegInst(exp, exp->getName()); } else if(ctx->unaryOp()->NOT()){ //not将非零值转换为0,零值转换为1 res = builder.createNotInst(exp, exp->getName()); } return res; } /* * @brief: visit mulexp * @details: * mulExp: unaryExp ((MUL | DIV | MOD) unaryExp)* */ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) { cout << "visitMulExp" << endl; Value* res = nullptr; cout << "mulExplhsin\n"; Value* lhs = any_cast(ctx->unaryExp(0)->accept(this)); cout << "mulExplhsout\n"; if(ctx->unaryExp().size() == 1){ cout << "unaryExp().size() = 1\n"; res = lhs; } else{ cout << "unaryExp().size() > 1\n"; for(size_t i = 1; i < ctx->unaryExp().size(); i++){ Value* rhs = any_cast(ctx->unaryExp(i)->accept(this)); auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(opNode->getText() == "*"){ res = builder.createMulInst(lhs, rhs, lhs->getName() + "*" + rhs->getName()); } else if(opNode->getText() == "/"){ res = builder.createDivInst(lhs, rhs, lhs->getName() + "/" + rhs->getName()); } else if(opNode->getText() == "%"){ std::cerr << "mod not implemented yet" << std::endl; // res = builder.createModInst(lhs, rhs, lhs->getName() + "%" + rhs->getName()); } } } return res; } /* * @brief: visit addexp * @details: * addExp: mulExp ((ADD | SUB) mulExp)* */ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) { cout << "visitAddExp" << endl; Value* res = nullptr; Value* lhs = any_cast(ctx->mulExp(0)->accept(this)); if(ctx->mulExp().size() == 1){ cout << "ctx->mulExp().size() = 1\n"; res = lhs; } else{ for(size_t i = 1; i < ctx->mulExp().size(); i++){ cout << "i = " << i << "\n"; Value* rhs = any_cast(ctx->mulExp(i)->accept(this)); auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(opNode->getText() == "+"){ res = builder.createAddInst(lhs, rhs, lhs->getName() + "+" + rhs->getName()); } else if(opNode->getText() == "-"){ res = builder.createSubInst(lhs, rhs, lhs->getName() + "-" + rhs->getName()); } } lhs = res; } return res; } /* * @brief: visit relexp * @details: * relExp: addExp ((LT | GT | LE | GE) addExp)* */ std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext *ctx) { cout << "visitRelExp" << endl; Value* res = nullptr; Value* lhs = any_cast(ctx->addExp(0)->accept(this)); if(ctx->addExp().size() == 1){ res = lhs; } else{ for(size_t i = 1; i < ctx->addExp().size(); i++){ Value* rhs = any_cast(ctx->addExp(i)->accept(this)); auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(lhs->getType() != rhs->getType()){ std::cerr << "type mismatch:type check not implemented" << std::endl; } Type* type = lhs->getType(); if(opNode->getText() == "<"){ if(type->isInt()) res = builder.createICmpLTInst(lhs, rhs, lhs->getName() + "<" + rhs->getName()); else if(type->isFloat()) res = builder.createFCmpLTInst(lhs, rhs, lhs->getName() + "<" + rhs->getName()); } else if(opNode->getText() == ">"){ if(type->isInt()) res = builder.createICmpGTInst(lhs, rhs, lhs->getName() + ">" + rhs->getName()); else if(type->isFloat()) res = builder.createFCmpGTInst(lhs, rhs, lhs->getName() + ">" + rhs->getName()); } else if(opNode->getText() == "<="){ if(type->isInt()) res = builder.createICmpLEInst(lhs, rhs, lhs->getName() + "<=" + rhs->getName()); else if(type->isFloat()) res = builder.createFCmpLEInst(lhs, rhs, lhs->getName() + "<=" + rhs->getName()); } else if(opNode->getText() == ">="){ if(type->isInt()) res = builder.createICmpGEInst(lhs, rhs, lhs->getName() + ">=" + rhs->getName()); else if(type->isFloat()) res = builder.createFCmpGEInst(lhs, rhs, lhs->getName() + ">=" + rhs->getName()); } } } return res; } /* * @brief: visit eqexp * @details: * eqExp: relExp ((EQ | NEQ) relExp)* */ std::any SysYIRGenerator::visitEqExp(SysYParser::EqExpContext* ctx) { cout << "visitEqExp" << endl; Value* res = nullptr; Value* lhs = any_cast(ctx->relExp(0)->accept(this)); if(ctx->relExp().size() == 1){ res = lhs; } else{ for(size_t i = 1; i < ctx->relExp().size(); i++){ Value* rhs = any_cast(ctx->relExp(i)->accept(this)); auto opNode = dynamic_cast(ctx->children[2 * i - 1]); if(lhs->getType() != rhs->getType()){ std::cerr << "type mismatch:type check not implemented" << std::endl; } Type* type = lhs->getType(); if(opNode->getText() == "=="){ if(type->isInt()) res = builder.createICmpEQInst(lhs, rhs, lhs->getName() + "==" + rhs->getName()); else if(type->isFloat()) res = builder.createFCmpEQInst(lhs, rhs, lhs->getName() + "==" + rhs->getName()); } else if(opNode->getText() == "!="){ if(type->isInt()) res = builder.createICmpNEInst(lhs, rhs, lhs->getName() + "!=" + rhs->getName()); else if(type->isFloat()) res = builder.createFCmpNEInst(lhs, rhs, lhs->getName() + "!=" + rhs->getName()); } } } return res; } /* * @brief: visit lAndexp * @details: * lAndExp: eqExp (AND eqExp)* */ std::any SysYIRGenerator::visitLAndExp(SysYParser::LAndExpContext* ctx) { cout << "visitLAndExp" << endl; auto currentBlock = builder.getBasicBlock(); // auto trueBlock = currentBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); auto falseBlock = currentBlock->getParent()->addBasicBlock("falseland" + std::to_string(++falseBlockNum)); Value* value = any_cast(ctx->eqExp(0)->accept(this)); auto trueBlock = currentBlock; for(size_t i = 1; i < ctx->eqExp().size(); i++){ trueBlock = trueBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); builder.createCondBrInst(value, currentBlock, falseBlock, {}, {}); builder.setPosition(trueBlock, trueBlock->end()); value = any_cast(ctx->eqExp(i)->accept(this)); } //结构trueblk条件跳转到falseblk // - trueBlock1->trueBlock2->trueBlock3->...->trueBlockn->nextblk //entry-| // -falseBlock->nextblk //需要在最后一个trueblock的末尾加上无条件跳转到下一个基本块的指令 // builder.createCondBrInst(value, trueBlock, falseBlock, {}, {}); return std::any(); } /* * @brief: visit lOrexp * @details: * lOrExp: lAndExp (OR lAndExp)* */ std::any SysYIRGenerator::visitLOrExp(SysYParser::LOrExpContext* ctx) { cout << "visitLOrExp" << endl; auto currentBlock = builder.getBasicBlock(); auto trueBlock = currentBlock->getParent()->addBasicBlock("trueland" + std::to_string(++trueBlockNum)); Value* value = any_cast(ctx->lAndExp(0)->accept(this)); auto falseBlock = currentBlock; for(size_t i = 1; i < ctx->lAndExp().size(); i++){ falseBlock = currentBlock->getParent()->addBasicBlock("falseland" + std::to_string(++falseBlockNum)); builder.createCondBrInst(value, trueBlock, falseBlock, {}, {}); builder.setPosition(falseBlock, falseBlock->end()); value = any_cast(ctx->lAndExp(i)->accept(this)); } //结构trueblk条件跳转到falseblk // - falseBlock1->falseBlock2->falseBlock3->...->falseBlockn->nextblk //entry-| // -trueBlock->nextblk //需要在最后一个falseblock的末尾加上无条件跳转到下一个基本块的指令 // builder.createCondBrInst(value, trueBlock, falseBlock, {}, {}); return std::any(); } /* * @brief: visit constexp * @details: * constExp: addExp; */ std::any SysYIRGenerator::visitConstExp(SysYParser::ConstExpContext* ctx) { cout << "visitConstExp" << endl; ConstantValue* res = nullptr; Value* value = any_cast(ctx->addExp()->accept(this)); if(isa(value)){ res = dyncast(value); } else{ std::cerr << "error constexp" << ctx->getText() << std::endl; } return res; } /* begin std::any SysYIRGenerator::visitConstGlobalDecl(SysYParser::ConstDeclContext *ctx, Type* type) { std::vector values; for (auto constDef : ctx->constDef()) { auto name = constDef->Ident()->getText(); // get its dimensions vector dims; for (auto dim : constDef->constExp()) dims.push_back(any_cast(dim->accept(this))); if (dims.size() == 0) { auto init = constDef->ASSIGN() ? any_cast((constDef->constInitVal()->constExp()->accept(this))) : nullptr; if (init && isa(init)){ Type *btype = type->as()->getBaseType(); if (btype->isInt() && init->getType()->isFloat()) init = ConstantValue::get((int)dynamic_cast(init)->getFloat()); else if (btype->isFloat() && init->getType()->isInt()) init = ConstantValue::get((float)dynamic_cast(init)->getInt()); } auto global_value = module->createGlobalValue(name, type, dims, init); symbols_table.insert(name, global_value); values.push_back(global_value); } else{ auto init = constDef->ASSIGN() ? any_cast(dims[0]) : nullptr; auto global_value = module->createGlobalValue(name, type, dims, init); if (constDef->ASSIGN()) { d = 0; n = 0; path.clear(); path = vector(dims.size(), 0); isalloca = false; current_type = global_value->getType()->as()->getBaseType(); current_global = global_value; numdims = global_value->getNumDims(); for (auto init : constDef->constInitVal()->constInitVal()) init->accept(this); // visitConstInitValue(init); } symbols_table.insert(name, global_value); values.push_back(global_value); } } return values; } std::any SysYIRGenerator::visitVarGlobalDecl(SysYParser::VarDeclContext *ctx, Type* type){ std::vector values; for (auto varDef : ctx->varDef()) { auto name = varDef->Ident()->getText(); // get its dimensions vector dims; for (auto dim : varDef->constExp()) dims.push_back(any_cast(dim->accept(this))); if (dims.size() == 0) { auto init = varDef->ASSIGN() ? any_cast((varDef->initVal()->exp()->accept(this))) : nullptr; if (init && isa(init)){ Type *btype = type->as()->getBaseType(); if (btype->isInt() && init->getType()->isFloat()) init = ConstantValue::get((int)dynamic_cast(init)->getFloat()); else if (btype->isFloat() && init->getType()->isInt()) init = ConstantValue::get((float)dynamic_cast(init)->getInt()); } auto global_value = module->createGlobalValue(name, type, dims, init); symbols_table.insert(name, global_value); values.push_back(global_value); } else{ auto init = varDef->ASSIGN() ? any_cast(dims[0]) : nullptr; auto global_value = module->createGlobalValue(name, type, dims, init); if (varDef->ASSIGN()) { d = 0; n = 0; path.clear(); path = vector(dims.size(), 0); isalloca = false; current_type = global_value->getType()->as()->getBaseType(); current_global = global_value; numdims = global_value->getNumDims(); for (auto init : varDef->initVal()->initVal()) init->accept(this); // visitInitValue(init); } symbols_table.insert(name, global_value); values.push_back(global_value); } } return values; } std::any SysYIRGenerator::visitConstLocalDecl(SysYParser::ConstDeclContext *ctx, Type* type){ std::vector values; // handle variables for (auto constDef : ctx->constDef()) { auto name = constDef->Ident()->getText(); vector dims; for (auto dim : constDef->constExp()) dims.push_back(any_cast(dim->accept(this))); auto alloca = builder.createAllocaInst(type, dims, name); symbols_table.insert(name, alloca); if (constDef->ASSIGN()) { if (alloca->getNumDims() == 0) { auto value = any_cast(constDef->constInitVal()->constExp()->accept(this)); if (isa(value)) { if (ctx->bType()->INT() && dynamic_cast(value)->isFloat()) value = ConstantValue::get((int)dynamic_cast(value)->getFloat()); else if (ctx->bType()->FLOAT() && dynamic_cast(value)->isInt()) value = ConstantValue::get((float)dynamic_cast(value)->getInt()); } else if (alloca->getType()->as()->getBaseType()->isInt() && value->getType()->isFloat()) value = builder.createFtoIInst(value); else if (alloca->getType()->as()->getBaseType()->isFloat() && value->getType()->isInt()) value = builder.createIToFInst(value); auto store = builder.createStoreInst(value, alloca); } else{ d = 0; n = 0; path.clear(); path = vector(alloca->getNumDims(), 0); isalloca = true; current_alloca = alloca; current_type = alloca->getType()->as()->getBaseType(); numdims = alloca->getNumDims(); for (auto init : constDef->constInitVal()->constInitVal()) init->accept(this); } } values.push_back(alloca); } return values; } std::any SysYIRGenerator::visitVarLocalDecl(SysYParser::VarDeclContext *ctx, Type* type){ std::vector values; for (auto varDef : ctx->varDef()) { auto name = varDef->Ident()->getText(); vector dims; for (auto dim : varDef->constExp()) dims.push_back(any_cast(dim->accept(this))); auto alloca = builder.createAllocaInst(type, dims, name); symbols_table.insert(name, alloca); if (varDef->ASSIGN()) { if (alloca->getNumDims() == 0) { auto value = any_cast(varDef->initVal()->exp()->accept(this)); if (isa(value)) { if (ctx->bType()->INT() && dynamic_cast(value)->isFloat()) value = ConstantValue::get((int)dynamic_cast(value)->getFloat()); else if (ctx->bType()->FLOAT() && dynamic_cast(value)->isInt()) value = ConstantValue::get((float)dynamic_cast(value)->getInt()); } else if (alloca->getType()->as()->getBaseType()->isInt() && value->getType()->isFloat()) value = builder.createFtoIInst(value); else if (alloca->getType()->as()->getBaseType()->isFloat() && value->getType()->isInt()) value = builder.createIToFInst(value); auto store = builder.createStoreInst(value, alloca); } else{ d = 0; n = 0; path.clear(); path = vector(alloca->getNumDims(), 0); isalloca = true; current_alloca = alloca; current_type = alloca->getType()->as()->getBaseType(); numdims = alloca->getNumDims(); for (auto init : varDef->initVal()->initVal()) init->accept(this); } } values.push_back(alloca); } return values; } end */ } // namespace sysy