[IR gen] introduced IR builder into LLVMIRGenerator
This commit is contained in:
@@ -5,8 +5,18 @@
|
|||||||
// TODO:对while、continue、break的测试
|
// TODO:对while、continue、break的测试
|
||||||
#include "LLVMIRGenerator.h"
|
#include "LLVMIRGenerator.h"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
using namespace std;
|
||||||
|
namespace sysy {
|
||||||
std::string LLVMIRGenerator::generateIR(SysYParser::CompUnitContext* unit) {
|
std::string LLVMIRGenerator::generateIR(SysYParser::CompUnitContext* unit) {
|
||||||
|
// 初始化自定义IR数据结构
|
||||||
|
irModule = std::make_unique<sysy::Module>();
|
||||||
|
irBuilder = sysy::IRBuilder(); // 初始化IR构建器
|
||||||
|
tempCounter = 0;
|
||||||
|
symbolTable.clear();
|
||||||
|
tmpTable.clear();
|
||||||
|
globalVars.clear();
|
||||||
|
inFunction = false;
|
||||||
|
|
||||||
visitCompUnit(unit);
|
visitCompUnit(unit);
|
||||||
return irStream.str();
|
return irStream.str();
|
||||||
}
|
}
|
||||||
@@ -25,7 +35,31 @@ std::string LLVMIRGenerator::getLLVMType(const std::string& type) {
|
|||||||
return "i32";
|
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) {
|
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()) {
|
for (auto decl : ctx->decl()) {
|
||||||
decl->accept(this);
|
decl->accept(this);
|
||||||
}
|
}
|
||||||
@@ -51,8 +85,10 @@ std::any LLVMIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) {
|
|||||||
|
|
||||||
if (varDef->ASSIGN()) {
|
if (varDef->ASSIGN()) {
|
||||||
value = std::any_cast<std::string>(varDef->initVal()->accept(this));
|
value = std::any_cast<std::string>(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";
|
irStream << "@" << varName << " = dso_local global " << llvmType << " " << value << ", align 4\n";
|
||||||
globalVars.push_back(varName); // 记录全局变量
|
globalVars.push_back(varName); // 记录全局变量
|
||||||
} else {
|
} else {
|
||||||
@@ -76,9 +112,9 @@ std::any LLVMIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
|||||||
try {
|
try {
|
||||||
value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
value = std::any_cast<std::string>(constDef->constInitVal()->accept(this));
|
||||||
} catch (...) {
|
} 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") {
|
if (llvmType == "float") {
|
||||||
try {
|
try {
|
||||||
double floatValue = std::stod(value);
|
double floatValue = std::stod(value);
|
||||||
@@ -87,7 +123,7 @@ std::any LLVMIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
|||||||
ss << "0x" << std::hex << std::uppercase << hexValue;
|
ss << "0x" << std::hex << std::uppercase << hexValue;
|
||||||
value = ss.str();
|
value = ss.str();
|
||||||
} catch (...) {
|
} 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;
|
left = temp;
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "SysYBaseVisitor.h"
|
#include "SysYBaseVisitor.h"
|
||||||
#include "SysYParser.h"
|
#include "SysYParser.h"
|
||||||
|
#include "IR.h"
|
||||||
|
#include "IRBuilder.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -8,13 +10,18 @@
|
|||||||
|
|
||||||
class LLVMIRGenerator : public SysYBaseVisitor {
|
class LLVMIRGenerator : public SysYBaseVisitor {
|
||||||
public:
|
public:
|
||||||
|
sysy::Module* getIRModule() const { return irModule.get(); }
|
||||||
|
|
||||||
std::string generateIR(SysYParser::CompUnitContext* unit);
|
std::string generateIR(SysYParser::CompUnitContext* unit);
|
||||||
std::string getIR() const { return irStream.str(); }
|
std::string getIR() const { return irStream.str(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::stringstream irStream;
|
std::unique_ptr<sysy::Module> irModule; // IR数据结构
|
||||||
|
std::stringstream irStream; // 文本输出流
|
||||||
|
sysy::IRBuilder irBuilder; // IR构建器
|
||||||
int tempCounter = 0;
|
int tempCounter = 0;
|
||||||
std::string currentVarType;
|
std::string currentVarType;
|
||||||
|
// std::map<std::string, sysy::Value*> symbolTable;
|
||||||
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
|
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
|
||||||
std::map<std::string, std::string> tmpTable;
|
std::map<std::string, std::string> tmpTable;
|
||||||
std::vector<std::string> globalVars;
|
std::vector<std::string> globalVars;
|
||||||
@@ -30,7 +37,8 @@ private:
|
|||||||
};
|
};
|
||||||
std::stack<LoopLabels> loopStack; // 用于管理循环的break和continue标签
|
std::stack<LoopLabels> loopStack; // 用于管理循环的break和continue标签
|
||||||
std::string getNextTemp();
|
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; // 标识当前是否处于函数内部
|
bool inFunction = false; // 标识当前是否处于函数内部
|
||||||
|
|
||||||
@@ -62,4 +70,9 @@ private:
|
|||||||
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
|
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
|
||||||
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
|
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
|
||||||
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
|
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
|
||||||
|
|
||||||
|
// 统一创建二元操作(同时生成数据结构和文本)
|
||||||
|
sysy::Value* createBinaryOp(SysYParser::ExpContext* lhs,
|
||||||
|
SysYParser::ExpContext* rhs,
|
||||||
|
sysy::Instruction::Kind opKind);
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user