工具类方法部分实现,实现部分IR生成

This commit is contained in:
rain2133
2025-06-21 14:33:56 +08:00
parent 2b038e671b
commit 8109d44232

View File

@@ -6,15 +6,20 @@
#include "IR.h"
#include <any>
#include <memory>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
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<Type *>(visitBType(constDecl->bType()));
for (const auto &constDef : constDecl->constDef()) {
std::vector<Value *> 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<Value *>(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<Type*>(ctx->bType()->accept(this));
for(auto constDef:ctx->constDef()){
constDef->accept(this);
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(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<Type *>(visitBType(varDecl->bType()));
for (const auto &varDef : varDecl->varDef()) {
std::vector<Value *> 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<Value *>(visitConstExp(constExp)));
}
}
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(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<Value*>(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<Value *> &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<ConstantValue *>(value);
if (constValue != nullptr) {
result.push_back(
ConstantValue::get(static_cast<float>(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<ConstantValue *>(value);
if (constValue != nullptr) {
result.push_back(
ConstantValue::get(static_cast<int>(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<Value*>(ctx->constExp()->accept(this));
else{
//还未实现数组初始化等功能待验证
std::cerr << "array initvalue not implemented yet" << std::endl;
// auto numConstInitVals = ctx->constInitVal().size();
// vector<Value*> initvalues;
// for(int i = 0; i < numConstInitVals; i++)
// initvalues.push_back(any_cast<Value*>(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<Type*>(ctx->funcType()->accept(this));
auto func = module->getFunction(funcName);
cout << "func: ";
returnType->print(cout);
cout << ' '<< funcName.c_str() << endl;
vector<Type*> paramTypes;
vector<string> paramNames;
if(ctx->funcFParams()){
for(auto funcParam:ctx->funcFParams()->funcFParam()){
Type* paramType = any_cast<Type*>(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<Type *>(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<Value*>(ctx->initVal()->accept(this)) : nullptr;
// const std::vector<Value *> 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<Value*>(ctx->exp()->accept(this));
else{
//还未实现数组初始化等功能待验证
std::cerr << "array initvalue not implemented yet" << std::endl;
// auto numConstInitVals = ctx->constInitVal().size();
// vector<Value*> initvalues;
// for(int i = 0; i < numConstInitVals; i++)
// initvalues.push_back(any_cast<Value*>(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<Value *>(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<Value*>(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<Value*>(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<Value *>(ctx->lValue()->accept(this));
cout << "getlval" << endl;//lvalue->print(cout);cout << ')';
auto rvalue = any_cast<Value *>(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<Value*> args;
if(ctx->funcRParams()){
for(auto exp:ctx->funcRParams()->exp()){
args.push_back(any_cast<Value*>(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<Value*>(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<Value *>(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<Value *>(ctx->unaryExp(i)->accept(this));
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<Value*>(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<Value*>(ctx->mulExp(i)->accept(this));
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<ConstantValue *>(*(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<ConstantValue *>(*(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<Value*>(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<Value*>(ctx->addExp(i)->accept(this));
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<Value*>(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<Value*>(ctx->relExp(i)->accept(this));
auto opNode = dynamic_cast<antlr4::tree::TerminalNode *>(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<Type *> &paramTypes,
const std::vector<std::string> &paramNames,
const std::vector<std::vector<Value *>> &paramDims, 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<Value*>(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<Value*>(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<Value*>(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<Value*>(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<Value*>(ctx->addExp()->accept(this));
if(isa<ConstantValue>(value)){
res = dyncast<ConstantValue>(value);
}
else{
std::cerr << "error constexp" << ctx->getText() << std::endl;
}
return res;
}
} // namespace sysy