From 8109d4423228e7ec85d38e02f5b7a318cdbcd389 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sat, 21 Jun 2025 14:33:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E9=83=A8=E5=88=86=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E9=83=A8=E5=88=86IR=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SysYIRGenerator.cpp | 894 +++++----------------------------------- 1 file changed, 112 insertions(+), 782 deletions(-) diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 5a7ccc2..c70869f 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -6,15 +6,20 @@ #include "IR.h" #include #include +#include +#include +#include +#include using namespace std; #include "SysYIRGenerator.h" + namespace sysy { /* * @brief: visit compUnit * @details: - * compUnit: (decl | funcDef)+; + * compUnit: (globalDecl | funcDef)+; */ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) { // create the IR module @@ -22,816 +27,141 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) { assert(pModule); module.reset(pModule); - SymbolTable::ModuleScope scope(symbols_table); + // 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")); + Utils::initExternalFunction(pModule, &builder); - 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 ? + pModule->enterNewScope(); + visitChildren(ctx); + pModule->leaveScope(); 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(); -} +std::any SysYIRGenerator::visitGlobalConstDecl(SysYParser::GlobalConstDeclContext *ctx){ + auto constDecl = ctx->constDecl(); + Type* type = std::any_cast(visitBType(constDecl->bType())); + for (const auto &constDef : constDecl->constDef()) { + std::vector dims = {}; + std::string name = constDef->Ident()->getText(); + auto constExps = constDef->constExp(); + if (!constExps.empty()) { + for (const auto &constExp : constExps) { + dims.push_back(std::any_cast(visitConstExp(constExp))); + } + } -/* - * @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); + ArrayValueTree* root = std::any_cast(constDef->constInitVal()->accept(this)); + ValueCounter values; + Utils::tree2Array(type, root, dims, dims.size(), values, &builder); + delete root; + // 创建全局常量变量,并更新符号表 + module->createConstVar(name, Type::getPointerType(type), values, dims); } 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; + +std::any SysYIRGenerator::visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *ctx) { + auto varDecl = ctx->varDecl(); + Type* type = std::any_cast(visitBType(varDecl->bType())); + for (const auto &varDef : varDecl->varDef()) { + std::vector dims = {}; + std::string name = varDef->Ident()->getText(); + auto constExps = varDef->constExp(); + if (!constExps.empty()) { + for (const auto &constExp : constExps) { + dims.push_back(std::any_cast(visitConstExp(constExp))); + } + } + + ArrayValueTree* root = std::any_cast(varDef->initVal()->accept(this)); + ValueCounter values; + Utils::tree2Array(type, root, dims, dims.size(), values, &builder); + delete root; + // 创建全局变量,并更新符号表 + module->createGlobalValue(name, Type::getPointerType(type), dims, values); + } 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); +void Utils::tree2Array(Type *type, ArrayValueTree *root, + const std::vector &dims, unsigned numDims, + ValueCounter &result, IRBuilder *builder) { + auto value = root->getValue(); + auto &children = root->getChildren(); + if (value != nullptr) { + if (type == value->getType()) { + result.push_back(value); + } else { + if (type == Type::getFloatType()) { + auto constValue = dynamic_cast(value); + if (constValue != nullptr) { + result.push_back( + ConstantValue::get(static_cast(constValue->getInt()))); + } else { + result.push_back(builder->createIToFInst(value)); } - 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); + } else { + auto constValue = dynamic_cast(value); + if (constValue != nullptr) { + result.push_back( + ConstantValue::get(static_cast(constValue->getFloat()))); + } else { + result.push_back(builder->createFtoIInst(value)); } - 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, {}, {}); + return; } - { // 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(Type::getIntType() ,(int)std::stol(text, 0, base)); - } else if (auto fLiteral = ctx->FLITERAL()) { - const auto text = fLiteral->getText(); - res = ConstantValue::get(Type::getFloatType(), (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()); + auto beforeSize = result.size(); + for (const auto &child : children) { + int begin = result.size(); + int newNumDims = 0; + for (unsigned i = 0; i < numDims - 1; i++) { + auto dim = dynamic_cast(*(dims.rbegin() + i))->getInt(); + if (begin % dim == 0) { + newNumDims += 1; + begin /= dim; + } else { + break; } } - lhs = res; + tree2Array(type, child.get(), dims, newNumDims, result, builder); + } + auto afterSize = result.size(); + + int blockSize = 1; + for (unsigned i = 0; i < numDims; i++) { + blockSize *= dynamic_cast(*(dims.rbegin() + i))->getInt(); } - 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()); - } + int num = blockSize - afterSize + beforeSize; + if (num > 0) { + if (type == Type::getFloatType()) { + result.push_back(ConstantValue::get(0.0F), num); + } else { + result.push_back(ConstantValue::get(0), num); } } - 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; -} +void Utils::createExternalFunction( + const std::vector ¶mTypes, + const std::vector ¶mNames, + const std::vector> ¶mDims, Type *returnType, + const std::string &funcName, Module *pModule, IRBuilder *pBuilder) { + auto funcType = Type::getFunctionType(returnType, paramTypes); + auto function = pModule->createExternalFunction(funcName, funcType); + auto entry = function->getEntryBlock(); + pBuilder->setPosition(entry, entry->end()); -/* - * @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)); + for (size_t i = 0; i < paramTypes.size(); ++i) { + auto alloca = pBuilder->createAllocaInst( + Type::getPointerType(paramTypes[i]), paramDims[i], paramNames[i]); + entry->insertArgument(alloca); + // pModule->addVariable(paramNames[i], alloca); } - //结构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; } } // namespace sysy \ No newline at end of file