Compare commits

..

8 Commits

Author SHA1 Message Date
rain2133
29f75e60a5 Merge remote-tracking branch 'origin/IRPrinter' into IRPrinter 2025-06-23 00:24:19 +08:00
rain2133
9d8930f5df fix % repeat in IR print 2025-06-23 00:22:15 +08:00
rain2133
3da2f3ec80 修复函数类型判断,终端跑通所有测试代码。Printer格式需要修复 2025-06-22 18:40:33 +08:00
rain2133
496e2abfb6 构建IR打印器,llvm风格,跑通大部分样例(9/10),待修复 2025-06-22 17:59:19 +08:00
lixuanwang
4711fb603b fixed bugs brought out by merging 2025-06-22 14:39:38 +08:00
lixuanwang
dda8bbe444 Merge branch 'array_add' 2025-06-22 14:24:00 +08:00
ladev789
25a8c72a9b [backend] it works 1.0 2025-06-22 14:06:14 +08:00
lixuanwang
232ed6d023 [backend] introduced rv32 backend 2025-06-21 17:26:50 +08:00
14 changed files with 760 additions and 135 deletions

2
.gitignore vendored
View File

@@ -50,3 +50,5 @@ GTAGS
__init__.py __init__.py
*.pyc *.pyc
.DS_*

View File

@@ -16,8 +16,8 @@ add_executable(sysyc
IR.cpp IR.cpp
SysYIRGenerator.cpp SysYIRGenerator.cpp
# Backend.cpp # Backend.cpp
# LLVMIRGenerator.cpp SysYIRPrinter.cpp
# LLVMIRGenerator_1.cpp RISCv32Backend.cpp
) )
target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include) target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_options(sysyc PRIVATE -frtti) target_compile_options(sysyc PRIVATE -frtti)

View File

@@ -91,7 +91,7 @@ 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));
if (irTmpTable.find(value) != irTmpTable.end() && sysy::isa<sysy::ConstantValue>(irTmpTable[value])) { if (irTmpTable.find(value) != irTmpTable.end() && isa<sysy::ConstantValue>(irTmpTable[value])) {
initValue = irTmpTable[value]; initValue = irTmpTable[value];
} }
} }
@@ -134,7 +134,7 @@ 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));
if (sysy::isa<sysy::ConstantValue>(irTmpTable[value])) { if (isa<sysy::ConstantValue>(irTmpTable[value])) {
initValue = irTmpTable[value]; initValue = irTmpTable[value];
} }
} catch (...) { } catch (...) {
@@ -310,7 +310,7 @@ std::any LLVMIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx) {
} else { } else {
irStream << " ret " << currentReturnType << " 0\n"; irStream << " ret " << currentReturnType << " 0\n";
sysy::IRBuilder builder(currentIRBlock); sysy::IRBuilder builder(currentIRBlock);
builder.createReturnInst(sysy::ConstantValue::get(getIRType("int"),0)); builder.createReturnInst(sysy::ConstantValue::get(0));
} }
} }
irStream << "}\n"; irStream << "}\n";
@@ -524,10 +524,10 @@ std::any LLVMIRGenerator::visitNumber(SysYParser::NumberContext* ctx) {
sysy::Value* irValue = nullptr; sysy::Value* irValue = nullptr;
if (ctx->ILITERAL()) { if (ctx->ILITERAL()) {
value = ctx->ILITERAL()->getText(); value = ctx->ILITERAL()->getText();
irValue = sysy::ConstantValue::get(getIRType("int"), std::stoi(value)); irValue = sysy::ConstantValue::get(std::stoi(value));
} else if (ctx->FLITERAL()) { } else if (ctx->FLITERAL()) {
value = ctx->FLITERAL()->getText(); value = ctx->FLITERAL()->getText();
irValue = sysy::ConstantValue::get(getIRType("float"), std::stof(value)); irValue = sysy::ConstantValue::get(std::stof(value));
} else { } else {
value = ""; value = "";
} }

0
src/Mem2Reg.cpp Normal file
View File

157
src/RISCv32Backend.cpp Normal file
View File

@@ -0,0 +1,157 @@
#include "RISCv32Backend.h"
#include <sstream>
#include <algorithm>
namespace sysy {
const std::vector<RISCv32CodeGen::PhysicalReg> RISCv32CodeGen::allocable_regs = {
PhysicalReg::T0, PhysicalReg::T1, PhysicalReg::T2, PhysicalReg::T3,
PhysicalReg::T4, PhysicalReg::T5, PhysicalReg::T6,
PhysicalReg::A0, PhysicalReg::A1, PhysicalReg::A2, PhysicalReg::A3,
PhysicalReg::A4, PhysicalReg::A5, PhysicalReg::A6, PhysicalReg::A7
};
std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) {
switch (reg) {
case PhysicalReg::T0: return "t0"; case PhysicalReg::T1: return "t1";
case PhysicalReg::T2: return "t2"; case PhysicalReg::T3: return "t3";
case PhysicalReg::T4: return "t4"; case PhysicalReg::T5: return "t5";
case PhysicalReg::T6: return "t6"; case PhysicalReg::A0: return "a0";
case PhysicalReg::A1: return "a1"; case PhysicalReg::A2: return "a2";
case PhysicalReg::A3: return "a3"; case PhysicalReg::A4: return "a4";
case PhysicalReg::A5: return "a5"; case PhysicalReg::A6: return "a6";
case PhysicalReg::A7: return "a7";
default: return "";
}
}
std::string RISCv32CodeGen::code_gen() {
std::stringstream ss;
ss << ".text\n";
ss << module_gen();
return ss.str();
}
std::string RISCv32CodeGen::module_gen() {
std::stringstream ss;
// 生成全局变量(数据段)
for (const auto& global : module->getGlobals()) {
ss << ".data\n";
ss << ".globl " << global->getName() << "\n";
ss << global->getName() << ":\n";
ss << " .word 0\n"; // 假设初始化为0
}
// 生成函数(文本段)
ss << ".text\n";
for (const auto& func : module->getFunctions()) {
ss << function_gen(func.second.get());
}
return ss.str();
}
std::string RISCv32CodeGen::function_gen(Function* func) {
std::stringstream ss;
// 函数标签
ss << ".globl " << func->getName() << "\n";
ss << func->getName() << ":\n";
// 序言:保存 ra分配堆栈
bool is_leaf = true; // 简化假设
ss << " addi sp, sp, -16\n";
ss << " sw ra, 12(sp)\n";
// 寄存器分配
auto alloc = register_allocation(func);
// 生成基本块代码
for (const auto& bb : func->getBasicBlocks()) {
ss << basicBlock_gen(bb.get(), alloc);
}
// 结尾:恢复 ra释放堆栈
ss << " lw ra, 12(sp)\n";
ss << " addi sp, sp, 16\n";
ss << " ret\n";
return ss.str();
}
std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc) {
std::stringstream ss;
ss << bb->getName() << ":\n";
for (const auto& inst : bb->getInstructions()) {
auto riscv_insts = instruction_gen(inst.get());
for (const auto& riscv_inst : riscv_insts) {
ss << " " << riscv_inst.opcode;
for (size_t i = 0; i < riscv_inst.operands.size(); ++i) {
if (i > 0) ss << ", ";
if (riscv_inst.operands[i].kind == Operand::Kind::Reg) {
auto it = alloc.reg_map.find(riscv_inst.operands[i].value);
if (it != alloc.reg_map.end()) {
ss << reg_to_string(it->second);
} else {
auto stack_it = alloc.stack_map.find(riscv_inst.operands[i].value);
if (stack_it != alloc.stack_map.end()) {
ss << stack_it->second << "(sp)";
} else {
ss << "%" << riscv_inst.operands[i].value->getName();
}
}
} else if (riscv_inst.operands[i].kind == Operand::Kind::Imm) {
ss << riscv_inst.operands[i].label;
} else {
ss << riscv_inst.operands[i].label;
}
}
ss << "\n";
}
}
return ss.str();
}
std::vector<RISCv32CodeGen::RISCv32Inst> RISCv32CodeGen::instruction_gen(Instruction* inst) {
std::vector<RISCv32Inst> insts;
if (auto bin = dynamic_cast<BinaryInst*>(inst)) {
std::string opcode;
if (bin->getKind() == BinaryInst::kAdd) opcode = "add";
else if (bin->getKind() == BinaryInst::kSub) opcode = "sub";
else if (bin->getKind() == BinaryInst::kMul) opcode = "mul";
else return insts; // 其他操作未实现
insts.emplace_back(opcode, std::vector<Operand>{
{Operand::Kind::Reg, bin},
{Operand::Kind::Reg, bin->getLhs()},
{Operand::Kind::Reg, bin->getRhs()}
});
} else if (auto load = dynamic_cast<LoadInst*>(inst)) {
insts.emplace_back("lw", std::vector<Operand>{
{Operand::Kind::Reg, load},
{Operand::Kind::Label, load->getPointer()->getName()}
});
} else if (auto store = dynamic_cast<StoreInst*>(inst)) {
insts.emplace_back("sw", std::vector<Operand>{
{Operand::Kind::Reg, store->getValue()},
{Operand::Kind::Label, store->getPointer()->getName()}
});
}
return insts;
}
void RISCv32CodeGen::eliminate_phi(Function* func) {
// TODO: 实现 phi 指令消除
}
std::map<Instruction*, std::set<Value*>> RISCv32CodeGen::liveness_analysis(Function* func) {
std::map<Instruction*, std::set<Value*>> live_sets;
// TODO: 实现活跃性分析
return live_sets;
}
std::map<Value*, std::set<Value*>> RISCv32CodeGen::build_interference_graph(
const std::map<Instruction*, std::set<Value*>>& live_sets) {
std::map<Value*, std::set<Value*>> graph;
// TODO: 实现干扰图构建
return graph;
}
RISCv32CodeGen::RegAllocResult RISCv32CodeGen::register_allocation(Function* func) {
RegAllocResult result;
// TODO: 实现寄存器分配
return result;
}
} // namespace sysy

67
src/RISCv32Backend.h Normal file
View File

@@ -0,0 +1,67 @@
#ifndef RISCV32_BACKEND_H
#define RISCV32_BACKEND_H
#include "IR.h"
#include <string>
#include <vector>
#include <map>
#include <set>
namespace sysy {
class RISCv32CodeGen {
public:
explicit RISCv32CodeGen(Module* mod) : module(mod) {}
std::string code_gen(); // 生成模块的汇编代码
private:
Module* module;
// 物理寄存器
enum class PhysicalReg {
T0, T1, T2, T3, T4, T5, T6, // x5-x7, x28-x31
A0, A1, A2, A3, A4, A5, A6, A7 // x10-x17
};
static const std::vector<PhysicalReg> allocable_regs;
// 操作数
struct Operand {
enum class Kind { Reg, Imm, Label };
Kind kind;
Value* value; // 用于寄存器
std::string label; // 用于标签或立即数
Operand(Kind k, Value* v) : kind(k), value(v), label("") {}
Operand(Kind k, const std::string& l) : kind(k), value(nullptr), label(l) {}
};
// RISC-V 指令
struct RISCv32Inst {
std::string opcode;
std::vector<Operand> operands;
RISCv32Inst(const std::string& op, const std::vector<Operand>& ops)
: opcode(op), operands(ops) {}
};
// 寄存器分配结果
struct RegAllocResult {
std::map<Value*, PhysicalReg> reg_map; // 虚拟寄存器到物理寄存器的映射
std::map<Value*, int> stack_map; // 虚拟寄存器到堆栈槽的映射
int stack_size; // 堆栈帧大小
};
// 后端方法
std::string module_gen();
std::string function_gen(Function* func);
std::string basicBlock_gen(BasicBlock* bb, const RegAllocResult& alloc);
std::vector<RISCv32Inst> instruction_gen(Instruction* inst);
RegAllocResult register_allocation(Function* func);
void eliminate_phi(Function* func);
std::map<Instruction*, std::set<Value*>> liveness_analysis(Function* func);
std::map<Value*, std::set<Value*>> build_interference_graph(
const std::map<Instruction*, std::set<Value*>>& live_sets);
std::string reg_to_string(PhysicalReg reg);
};
} // namespace sysy
#endif // RISCV32_BACKEND_H

View File

@@ -73,10 +73,12 @@ std::any SysYIRGenerator::visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *c
} }
} }
ValueCounter values = {};
if (varDef->initVal() != nullptr) {
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(varDef->initVal()->accept(this)); ArrayValueTree* root = std::any_cast<ArrayValueTree *>(varDef->initVal()->accept(this));
ValueCounter values;
Utils::tree2Array(type, root, dims, dims.size(), values, &builder); Utils::tree2Array(type, root, dims, dims.size(), values, &builder);
delete root; delete root;
}
// 创建全局变量,并更新符号表 // 创建全局变量,并更新符号表
module->createGlobalValue(name, Type::getPointerType(type), dims, values); module->createGlobalValue(name, Type::getPointerType(type), dims, values);
} }
@@ -456,7 +458,7 @@ std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext *ctx) {
returnValue = std::any_cast<Value *>(visitExp(ctx->exp())); returnValue = std::any_cast<Value *>(visitExp(ctx->exp()));
} }
Type* funcType = builder.getBasicBlock()->getParent()->getType(); Type* funcType = builder.getBasicBlock()->getParent()->getReturnType();
if (funcType!= returnValue->getType() && returnValue != nullptr) { if (funcType!= returnValue->getType() && returnValue != nullptr) {
ConstantValue * constValue = dynamic_cast<ConstantValue *>(returnValue); ConstantValue * constValue = dynamic_cast<ConstantValue *>(returnValue);
if (constValue != nullptr) { if (constValue != nullptr) {

479
src/SysYIRPrinter.cpp Normal file
View File

@@ -0,0 +1,479 @@
#include "SysYIRPrinter.h"
#include <cassert>
#include <fstream>
#include <iostream>
#include <string>
#include "IR.h"
namespace sysy {
void SysYPrinter::printIR() {
const auto &functions = pModule->getFunctions();
//TODO: Print target datalayout and triple (minimal required by LLVM)
printGlobalVariable();
for (const auto &iter : functions) {
if (iter.second->getName() == "main") {
printFunction(iter.second.get());
break;
}
}
for (const auto &iter : functions) {
if (iter.second->getName() != "main") {
printFunction(iter.second.get());
}
}
}
std::string SysYPrinter::getTypeString(Type *type) {
if (type->isVoid()) {
return "void";
} else if (type->isInt()) {
return "i32";
} else if (type->isFloat()) {
return "float";
} else if (auto ptrType = dynamic_cast<PointerType*>(type)) {
return getTypeString(ptrType->getBaseType()) + "*";
} else if (auto ptrType = dynamic_cast<FunctionType*>(type)) {
return getTypeString(ptrType->getReturnType());
}
assert(false && "Unsupported type");
return "";
}
std::string SysYPrinter::getValueName(Value *value) {
if (auto global = dynamic_cast<GlobalValue*>(value)) {
return "@" + global->getName();
} else if (auto inst = dynamic_cast<Instruction*>(value)) {
return "%" + inst->getName();
} else if (auto constVal = dynamic_cast<ConstantValue*>(value)) {
if (constVal->isFloat()) {
return std::to_string(constVal->getFloat());
}
return std::to_string(constVal->getInt());
} else if (auto constVar = dynamic_cast<ConstantVariable*>(value)) {
return constVar->getName();
}
assert(false && "Unknown value type");
return "";
}
void SysYPrinter::printType(Type *type) {
std::cout << getTypeString(type);
}
void SysYPrinter::printValue(Value *value) {
std::cout << getValueName(value);
}
void SysYPrinter::printGlobalVariable() {
auto &globals = pModule->getGlobals();
for (const auto &global : globals) {
std::cout << "@" << global->getName() << " = global ";
auto baseType = dynamic_cast<PointerType *>(global->getType())->getBaseType();
printType(baseType);
if (global->getNumDims() > 0) {
// Array type
std::cout << " [";
for (unsigned i = 0; i < global->getNumDims(); i++) {
if (i > 0) std::cout << " x ";
std::cout << getValueName(global->getDim(i));
}
std::cout << "]";
}
std::cout << " ";
if (global->getNumDims() > 0) {
// Array initializer
std::cout << "[";
auto values = global->getInitValues();
auto counterValues = values.getValues();
auto counterNumbers = values.getNumbers();
for (size_t i = 0; i < counterNumbers.size(); i++) {
if (i > 0) std::cout << ", ";
if (baseType->isFloat()) {
std::cout << "float " << dynamic_cast<ConstantValue*>(counterValues[i])->getFloat();
} else {
std::cout << "i32 " << dynamic_cast<ConstantValue*>(counterValues[i])->getInt();
}
}
std::cout << "]";
} else {
// Scalar initializer
if (baseType->isFloat()) {
std::cout << "float " << dynamic_cast<ConstantValue*>(global->getByIndex(0))->getFloat();
} else {
std::cout << "i32 " << dynamic_cast<ConstantValue*>(global->getByIndex(0))->getInt();
}
}
std::cout << ", align 4" << std::endl;
}
}
void SysYPrinter::printFunction(Function *function) {
// Function signature
std::cout << "define ";
printType(function->getReturnType());
std::cout << " @" << function->getName() << "(";
auto entryBlock = function->getEntryBlock();
auto &args = entryBlock->getArguments();
for (size_t i = 0; i < args.size(); i++) {
if (i > 0) std::cout << ", ";
printType(args[i]->getType());
std::cout << " %" << args[i]->getName();
}
std::cout << ") {" << std::endl;
// Function body
for (const auto &blockIter : function->getBasicBlocks()) {
// Basic block label
BasicBlock* blockPtr = blockIter.get();
if (blockPtr == function->getEntryBlock()) {
std::cout << "entry:" << std::endl;
} else if (!blockPtr->getName().empty()) {
std::cout << blockPtr->getName() << ":" << std::endl;
}
// Instructions
for (const auto &instIter : blockIter->getInstructions()) {
auto inst = instIter.get();
std::cout << " ";
printInst(inst);
}
}
std::cout << "}" << std::endl << std::endl;
}
void SysYPrinter::printInst(Instruction *pInst) {
using Kind = Instruction::Kind;
switch (pInst->getKind()) {
case Kind::kAdd:
case Kind::kSub:
case Kind::kMul:
case Kind::kDiv:
case Kind::kRem:
case Kind::kFAdd:
case Kind::kFSub:
case Kind::kFMul:
case Kind::kFDiv:
case Kind::kICmpEQ:
case Kind::kICmpNE:
case Kind::kICmpLT:
case Kind::kICmpGT:
case Kind::kICmpLE:
case Kind::kICmpGE:
case Kind::kFCmpEQ:
case Kind::kFCmpNE:
case Kind::kFCmpLT:
case Kind::kFCmpGT:
case Kind::kFCmpLE:
case Kind::kFCmpGE:
case Kind::kAnd:
case Kind::kOr: {
auto binInst = dynamic_cast<BinaryInst *>(pInst);
// Print result variable if exists
if (!binInst->getName().empty()) {
std::cout << "%" << binInst->getName() << " = ";
}
// Operation name
switch (pInst->getKind()) {
case Kind::kAdd: std::cout << "add"; break;
case Kind::kSub: std::cout << "sub"; break;
case Kind::kMul: std::cout << "mul"; break;
case Kind::kDiv: std::cout << "sdiv"; break;
case Kind::kRem: std::cout << "srem"; break;
case Kind::kFAdd: std::cout << "fadd"; break;
case Kind::kFSub: std::cout << "fsub"; break;
case Kind::kFMul: std::cout << "fmul"; break;
case Kind::kFDiv: std::cout << "fdiv"; break;
case Kind::kICmpEQ: std::cout << "icmp eq"; break;
case Kind::kICmpNE: std::cout << "icmp ne"; break;
case Kind::kICmpLT: std::cout << "icmp slt"; break;
case Kind::kICmpGT: std::cout << "icmp sgt"; break;
case Kind::kICmpLE: std::cout << "icmp sle"; break;
case Kind::kICmpGE: std::cout << "icmp sge"; break;
case Kind::kFCmpEQ: std::cout << "fcmp oeq"; break;
case Kind::kFCmpNE: std::cout << "fcmp one"; break;
case Kind::kFCmpLT: std::cout << "fcmp olt"; break;
case Kind::kFCmpGT: std::cout << "fcmp ogt"; break;
case Kind::kFCmpLE: std::cout << "fcmp ole"; break;
case Kind::kFCmpGE: std::cout << "fcmp oge"; break;
case Kind::kAnd: std::cout << "and"; break;
case Kind::kOr: std::cout << "or"; break;
default: break;
}
// Types and operands
std::cout << " ";
printType(binInst->getType());
std::cout << " ";
printValue(binInst->getLhs());
std::cout << ", ";
printValue(binInst->getRhs());
std::cout << std::endl;
} break;
case Kind::kNeg:
case Kind::kNot:
case Kind::kFNeg:
case Kind::kFNot:
case Kind::kFtoI:
case Kind::kBitFtoI:
case Kind::kItoF:
case Kind::kBitItoF: {
auto unyInst = dynamic_cast<UnaryInst *>(pInst);
if (!unyInst->getName().empty()) {
std::cout << "%" << unyInst->getName() << " = ";
}
switch (pInst->getKind()) {
case Kind::kNeg: std::cout << "sub "; break;
case Kind::kNot: std::cout << "xor "; break;
case Kind::kFNeg: std::cout << "fneg "; break;
case Kind::kFNot: std::cout << "fneg "; break; // FNot not standard, map to fneg
case Kind::kFtoI: std::cout << "fptosi "; break;
case Kind::kBitFtoI: std::cout << "bitcast "; break;
case Kind::kItoF: std::cout << "sitofp "; break;
case Kind::kBitItoF: std::cout << "bitcast "; break;
default: break;
}
printType(unyInst->getType());
std::cout << " ";
// Special handling for negation
if (pInst->getKind() == Kind::kNeg || pInst->getKind() == Kind::kNot) {
std::cout << "i32 0, ";
}
printValue(pInst->getOperand(0));
// For bitcast, need to specify destination type
if (pInst->getKind() == Kind::kBitFtoI || pInst->getKind() == Kind::kBitItoF) {
std::cout << " to ";
printType(unyInst->getType());
}
std::cout << std::endl;
} break;
case Kind::kCall: {
auto callInst = dynamic_cast<CallInst *>(pInst);
auto function = callInst->getCallee();
if (!callInst->getName().empty()) {
std::cout << "%" << callInst->getName() << " = ";
}
std::cout << "call ";
printType(callInst->getType());
std::cout << " @" << function->getName() << "(";
auto params = callInst->getArguments();
bool first = true;
for (auto &param : params) {
if (!first) std::cout << ", ";
first = false;
printType(param->getValue()->getType());
std::cout << " ";
printValue(param->getValue());
}
std::cout << ")" << std::endl;
} break;
case Kind::kCondBr: {
auto condBrInst = dynamic_cast<CondBrInst *>(pInst);
std::cout << "br i1 ";
printValue(condBrInst->getCondition());
std::cout << ", label %" << condBrInst->getThenBlock()->getName();
std::cout << ", label %" << condBrInst->getElseBlock()->getName();
std::cout << std::endl;
} break;
case Kind::kBr: {
auto brInst = dynamic_cast<UncondBrInst *>(pInst);
std::cout << "br label %" << brInst->getBlock()->getName();
std::cout << std::endl;
} break;
case Kind::kReturn: {
auto retInst = dynamic_cast<ReturnInst *>(pInst);
std::cout << "ret ";
if (retInst->getNumOperands() != 0) {
printType(retInst->getOperand(0)->getType());
std::cout << " ";
printValue(retInst->getOperand(0));
} else {
std::cout << "void";
}
std::cout << std::endl;
} break;
case Kind::kAlloca: {
auto allocaInst = dynamic_cast<AllocaInst *>(pInst);
std::cout << "%" << allocaInst->getName() << " = alloca ";
auto baseType = dynamic_cast<PointerType *>(allocaInst->getType())->getBaseType();
printType(baseType);
if (allocaInst->getNumDims() > 0) {
std::cout << ", ";
for (size_t i = 0; i < allocaInst->getNumDims(); i++) {
if (i > 0) std::cout << ", ";
printType(Type::getIntType());
std::cout << " ";
printValue(allocaInst->getDim(i));
}
}
std::cout << ", align 4" << std::endl;
} break;
case Kind::kLoad: {
auto loadInst = dynamic_cast<LoadInst *>(pInst);
std::cout << "%" << loadInst->getName() << " = load ";
printType(loadInst->getType());
std::cout << ", ";
printType(loadInst->getPointer()->getType());
std::cout << " ";
printValue(loadInst->getPointer());
if (loadInst->getNumIndices() > 0) {
std::cout << ", ";
for (size_t i = 0; i < loadInst->getNumIndices(); i++) {
if (i > 0) std::cout << ", ";
printType(Type::getIntType());
std::cout << " ";
printValue(loadInst->getIndex(i));
}
}
std::cout << ", align 4" << std::endl;
} break;
case Kind::kLa: {
auto laInst = dynamic_cast<LaInst *>(pInst);
std::cout << "%" << laInst->getName() << " = getelementptr inbounds ";
auto ptrType = dynamic_cast<PointerType*>(laInst->getPointer()->getType());
printType(ptrType->getBaseType());
std::cout << ", ";
printType(laInst->getPointer()->getType());
std::cout << " ";
printValue(laInst->getPointer());
std::cout << ", ";
for (size_t i = 0; i < laInst->getNumIndices(); i++) {
if (i > 0) std::cout << ", ";
printType(Type::getIntType());
std::cout << " ";
printValue(laInst->getIndex(i));
}
std::cout << std::endl;
} break;
case Kind::kStore: {
auto storeInst = dynamic_cast<StoreInst *>(pInst);
std::cout << "store ";
printType(storeInst->getValue()->getType());
std::cout << " ";
printValue(storeInst->getValue());
std::cout << ", ";
printType(storeInst->getPointer()->getType());
std::cout << " ";
printValue(storeInst->getPointer());
if (storeInst->getNumIndices() > 0) {
std::cout << ", ";
for (size_t i = 0; i < storeInst->getNumIndices(); i++) {
if (i > 0) std::cout << ", ";
printType(Type::getIntType());
std::cout << " ";
printValue(storeInst->getIndex(i));
}
}
std::cout << ", align 4" << std::endl;
} break;
case Kind::kMemset: {
auto memsetInst = dynamic_cast<MemsetInst *>(pInst);
std::cout << "call void @llvm.memset.p0.";
printType(memsetInst->getPointer()->getType());
std::cout << "(";
printType(memsetInst->getPointer()->getType());
std::cout << " ";
printValue(memsetInst->getPointer());
std::cout << ", i8 ";
printValue(memsetInst->getValue());
std::cout << ", i32 ";
printValue(memsetInst->getSize());
std::cout << ", i1 false)" << std::endl;
} break;
case Kind::kPhi: {
auto phiInst = dynamic_cast<PhiInst *>(pInst);
std::cout << "%" << phiInst->getName() << " = phi ";
printType(phiInst->getType());
for (unsigned i = 0; i < phiInst->getNumOperands(); i += 2) {
if (i > 0) std::cout << ", ";
std::cout << "[ ";
printValue(phiInst->getOperand(i));
std::cout << ", %" << dynamic_cast<BasicBlock*>(phiInst->getOperand(i+1))->getName() << " ]";
}
std::cout << std::endl;
} break;
case Kind::kGetSubArray: {
auto getSubArrayInst = dynamic_cast<GetSubArrayInst *>(pInst);
std::cout << "%" << getSubArrayInst->getName() << " = getelementptr inbounds ";
auto ptrType = dynamic_cast<PointerType*>(getSubArrayInst->getFatherArray()->getType());
printType(ptrType->getBaseType());
std::cout << ", ";
printType(getSubArrayInst->getFatherArray()->getType());
std::cout << " ";
printValue(getSubArrayInst->getFatherArray());
std::cout << ", ";
bool firstIndex = true;
for (auto &index : getSubArrayInst->getIndices()) {
if (!firstIndex) std::cout << ", ";
firstIndex = false;
printType(Type::getIntType());
std::cout << " ";
printValue(index->getValue());
}
std::cout << std::endl;
} break;
default:
assert(false && "Unsupported instruction kind");
break;
}
}
} // namespace sysy

View File

@@ -96,7 +96,7 @@ class IRBuilder {
std::string newName; std::string newName;
if (name.empty()) { if (name.empty()) {
std::stringstream ss; std::stringstream ss;
ss << "%" << tmpIndex; ss << tmpIndex;
newName = ss.str(); newName = ss.str();
tmpIndex++; tmpIndex++;
} else { } else {
@@ -136,7 +136,7 @@ class IRBuilder {
std::string newName; std::string newName;
if (name.empty()) { if (name.empty()) {
std::stringstream ss; std::stringstream ss;
ss << "%" << tmpIndex; ss << tmpIndex;
newName = ss.str(); newName = ss.str();
tmpIndex++; tmpIndex++;
} else { } else {
@@ -221,7 +221,7 @@ class IRBuilder {
std::string newName; std::string newName;
if (name.empty() && callee->getReturnType() != Type::getVoidType()) { if (name.empty() && callee->getReturnType() != Type::getVoidType()) {
std::stringstream ss; std::stringstream ss;
ss << "%" << tmpIndex; ss << tmpIndex;
newName = ss.str(); newName = ss.str();
tmpIndex++; tmpIndex++;
} else { } else {
@@ -268,7 +268,7 @@ class IRBuilder {
std::string newName; std::string newName;
if (name.empty()) { if (name.empty()) {
std::stringstream ss; std::stringstream ss;
ss << "%" << tmpIndex; ss << tmpIndex;
newName = ss.str(); newName = ss.str();
tmpIndex++; tmpIndex++;
} else { } else {
@@ -284,7 +284,7 @@ class IRBuilder {
std::string newName; std::string newName;
if (name.empty()) { if (name.empty()) {
std::stringstream ss; std::stringstream ss;
ss << "%" << tmpIndex; ss << tmpIndex;
newName = ss.str(); newName = ss.str();
tmpIndex++; tmpIndex++;
} else { } else {

View File

@@ -1,99 +0,0 @@
#pragma once
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include "IR.h" // 引入 SysY IR 头文件
#include "IRBuilder.h"
#include <sstream>
#include <map>
#include <vector>
#include <stack>
#include <memory>
class LLVMIRGenerator : public SysYBaseVisitor {
public:
// 生成 IR文本和数据结构
std::string generateIR(SysYParser::CompUnitContext* unit);
// 获取文本格式的 LLVM IR
std::string getIR() const { return irStream.str(); }
// 获取 SysY IR 数据结构
sysy::Module* getModule() const { return module.get(); }
private:
// 文本输出相关
std::stringstream irStream;
int tempCounter = 0; // 临时变量计数器
std::string currentVarType; // 当前变量类型(文本 IR 用)
// 符号表:映射变量名到 {分配地址/寄存器, 类型}(文本 IR
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
// 临时变量表:映射临时变量名到类型(文本 IR
std::map<std::string, std::string> tmpTable;
std::vector<std::string> globalVars; // 全局变量列表(文本 IR
// SysY IR 数据结构
std::unique_ptr<sysy::Module> module; // SysY IR 模块
// 符号表:映射变量名到 SysY IR 的 Value 指针
std::map<std::string, sysy::Value*> irSymbolTable;
// 临时变量表:映射临时变量名到 SysY IR 的 Value 指针
std::map<std::string, sysy::Value*> irTmpTable;
// 当前上下文
std::string currentFunction; // 当前函数名(文本 IR
std::string currentReturnType; // 当前函数返回类型(文本 IR
sysy::Function* currentIRFunction = nullptr; // 当前 SysY IR 函数
sysy::BasicBlock* currentIRBlock = nullptr; // 当前 SysY IR 基本块
// 循环控制
std::vector<std::string> breakStack; // break 标签栈(文本 IR
std::vector<std::string> continueStack; // continue 标签栈(文本 IR
bool hasReturn = false; // 是否有返回语句(文本 IR
struct LoopLabels {
std::string breakLabel; // break 跳转目标标签(文本 IR
std::string continueLabel; // continue 跳转目标标签(文本 IR
sysy::BasicBlock* irBreakBlock = nullptr; // break 跳转目标块SysY IR
sysy::BasicBlock* irContinueBlock = nullptr; // continue 跳转目标块SysY IR
};
std::stack<LoopLabels> loopStack; // 管理循环的 break 和 continue 标签
bool inFunction = false; // 标记是否在函数内部
// 辅助函数(文本 IR
std::string getNextTemp(); // 获取下一个临时变量名
std::string getLLVMType(const std::string& type); // 转换 SysY 类型到 LLVM 类型
// 辅助函数SysY IR
sysy::Type* getIRType(const std::string& type); // 转换 SysY 类型到 SysY IR 类型
std::string getIRTempName(); // 获取 SysY IR 临时变量名
void setIRPosition(sysy::BasicBlock* block); // 设置当前 IR 插入点
// 访问方法
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
std::any visitLValue(SysYParser::LValueContext* ctx) override;
// std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitPrimExp(SysYParser::PrimExpContext* ctx) override;
std::any visitParenExp(SysYParser::ParenExpContext* ctx) override;
std::any visitNumber(SysYParser::NumberContext* ctx) override;
std::any visitString(SysYParser::StringContext* ctx) override;
std::any visitCall(SysYParser::CallContext* ctx) override;
std::any visitUnExp(SysYParser::UnExpContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
std::any visitAssignStmt(SysYParser::AssignStmtContext* ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext* ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext* ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext* ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext* ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext* ctx) override;
};

0
src/include/Mem2Reg.h Normal file
View File

View File

@@ -0,0 +1,29 @@
#pragma once
#include <string>
#include "IR.h"
namespace sysy {
class SysYPrinter {
private:
Module *pModule;
public:
explicit SysYPrinter(Module *pModule) : pModule(pModule) {}
public:
void printIR();
void printGlobalVariable();
void printFunction(Function *function);
void printInst(Instruction *pInst);
void printType(Type *type);
void printValue(Value *value);
public:
static std::string getOperandName(Value *operand);
std::string getTypeString(Type *type);
std::string getValueName(Value *value);
};
} // namespace sysy

View File

@@ -8,6 +8,7 @@ using namespace std;
using namespace antlr4; using namespace antlr4;
// #include "Backend.h" // #include "Backend.h"
#include "SysYIRGenerator.h" #include "SysYIRGenerator.h"
#include "SysYIRPrinter.h"
// #include "LLVMIRGenerator.h" // #include "LLVMIRGenerator.h"
using namespace sysy; using namespace sysy;
@@ -76,22 +77,9 @@ int main(int argc, char **argv) {
SysYIRGenerator generator; SysYIRGenerator generator;
generator.visitCompUnit(moduleAST); generator.visitCompUnit(moduleAST);
auto moduleIR = generator.get(); auto moduleIR = generator.get();
// moduleIR->print(cout); SysYPrinter printer(moduleIR);
printer.printIR();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
// else if (argStopAfter == "llvmir") {
// LLVMIRGenerator llvmirGenerator;
// llvmirGenerator.generateIR(moduleAST); // 使用公共接口生成 IR
// cout << llvmirGenerator.getIR();
// return EXIT_SUCCESS;
// }
// // generate assembly
// CodeGen codegen(moduleIR);
// string asmCode = codegen.code_gen();
// cout << asmCode << endl;
// if (argStopAfter == "asm")
// return EXIT_SUCCESS;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }