From 5e84961dcff7bb973e82e66bc6e07539f8288091 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Mon, 9 Jun 2025 00:47:47 +0800 Subject: [PATCH] [IR gen] introduced IR builder into LLVMIRGenerator --- src/LLVMIRGenerator.cpp | 47 ++++++++++++++++++++++++++++++++++++----- src/LLVMIRGenerator.h | 17 +++++++++++++-- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/LLVMIRGenerator.cpp b/src/LLVMIRGenerator.cpp index 51eaa07..04f2686 100644 --- a/src/LLVMIRGenerator.cpp +++ b/src/LLVMIRGenerator.cpp @@ -5,8 +5,18 @@ // TODO:对while、continue、break的测试 #include "LLVMIRGenerator.h" #include - +using namespace std; +namespace sysy { std::string LLVMIRGenerator::generateIR(SysYParser::CompUnitContext* unit) { + // 初始化自定义IR数据结构 + irModule = std::make_unique(); + irBuilder = sysy::IRBuilder(); // 初始化IR构建器 + tempCounter = 0; + symbolTable.clear(); + tmpTable.clear(); + globalVars.clear(); + inFunction = false; + visitCompUnit(unit); return irStream.str(); } @@ -25,7 +35,31 @@ std::string LLVMIRGenerator::getLLVMType(const std::string& type) { return "i32"; } +sysy::Type* LLVMIRGenerator::getSysYType(const std::string& typeStr) { + if (typeStr == "int") return sysy::Type::getIntType(); + if (typeStr == "float") return sysy::Type::getFloatType(); + if (typeStr == "void") return sysy::Type::getVoidType(); + // 处理指针类型等 + return sysy::Type::getIntType(); +} + std::any LLVMIRGenerator::visitCompUnit(SysYParser::CompUnitContext* ctx) { + 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); + + // 创建运行时库函数 + irModule->createFunction("getint", sysy::FunctionType::get(type_i32, {})); + irModule->createFunction("getch", sysy::FunctionType::get(type_i32, {})); + irModule->createFunction("getfloat", sysy::FunctionType::get(type_f32, {})); + //TODO: 添加更多运行时库函数 + irStream << "declare i32 @getint()\n"; + irStream << "declare i32 @getch()\n"; + irStream << "declare float @getfloat()\n"; + //TODO: 添加更多运行时库函数的文本IR + for (auto decl : ctx->decl()) { decl->accept(this); } @@ -51,8 +85,10 @@ std::any LLVMIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) { if (varDef->ASSIGN()) { value = std::any_cast(varDef->initVal()->accept(this)); + } else { + std::cout << "[WR-Release-01]Warning: Global variable '" << varName + << "' is declared without initialization, defaulting to 0.\n"; } - irStream << "@" << varName << " = dso_local global " << llvmType << " " << value << ", align 4\n"; globalVars.push_back(varName); // 记录全局变量 } else { @@ -76,9 +112,9 @@ std::any LLVMIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) { try { value = std::any_cast(constDef->constInitVal()->accept(this)); } catch (...) { - throw std::runtime_error("Const value must be initialized upon definition."); + throw std::runtime_error("[ERR-Release-01]Const value must be initialized upon definition."); } - + // 如果是 float 类型,转换为十六进制表示 if (llvmType == "float") { try { double floatValue = std::stod(value); @@ -87,7 +123,7 @@ std::any LLVMIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) { ss << "0x" << std::hex << std::uppercase << hexValue; value = ss.str(); } catch (...) { - throw std::runtime_error("Invalid float literal: " + value); + throw std::runtime_error("[ERR-Release-02]Invalid float literal: " + value); } } @@ -632,4 +668,5 @@ std::any LLVMIRGenerator::visitLOrExp(SysYParser::LOrExpContext* ctx) { left = temp; } return left; +} } \ No newline at end of file diff --git a/src/LLVMIRGenerator.h b/src/LLVMIRGenerator.h index 2d3aada..85f1a34 100644 --- a/src/LLVMIRGenerator.h +++ b/src/LLVMIRGenerator.h @@ -1,6 +1,8 @@ #pragma once #include "SysYBaseVisitor.h" #include "SysYParser.h" +#include "IR.h" +#include "IRBuilder.h" #include #include #include @@ -8,13 +10,18 @@ class LLVMIRGenerator : public SysYBaseVisitor { public: + sysy::Module* getIRModule() const { return irModule.get(); } + std::string generateIR(SysYParser::CompUnitContext* unit); std::string getIR() const { return irStream.str(); } private: - std::stringstream irStream; + std::unique_ptr irModule; // IR数据结构 + std::stringstream irStream; // 文本输出流 + sysy::IRBuilder irBuilder; // IR构建器 int tempCounter = 0; std::string currentVarType; + // std::map symbolTable; std::map> symbolTable; std::map tmpTable; std::vector globalVars; @@ -30,7 +37,8 @@ private: }; std::stack loopStack; // 用于管理循环的break和continue标签 std::string getNextTemp(); - std::string getLLVMType(const std::string& type); + std::string getLLVMType(const std::string&); + sysy::Type* LLVMIRGenerator::getSysYType(const std::string&); bool inFunction = false; // 标识当前是否处于函数内部 @@ -62,4 +70,9 @@ private: std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override; std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override; std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override; + + // 统一创建二元操作(同时生成数据结构和文本) + sysy::Value* createBinaryOp(SysYParser::ExpContext* lhs, + SysYParser::ExpContext* rhs, + sysy::Instruction::Kind opKind); }; \ No newline at end of file