From a509dabbf0486f038c65c5476f4a208bd4d62819 Mon Sep 17 00:00:00 2001 From: Lixuanwang Date: Tue, 15 Jul 2025 11:32:53 +0800 Subject: [PATCH] =?UTF-8?q?[backend]=E8=A7=A3=E5=86=B3=E4=BA=86=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E8=AE=BF=E5=AD=98=E5=9C=B0=E5=9D=80=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=8C=E5=8A=A0=E5=85=A5=E4=BA=86=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=8E=A7=E5=88=B6=E7=9A=84=E4=B8=AD=E7=AB=AF=E3=80=81?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E8=B0=83=E8=AF=95=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/RISCv64Backend.cpp | 124 +++++++++++++++++++++++++++++++---------- src/RISCv64Backend.h | 5 ++ src/include/IR.h | 4 ++ src/sysyc.cpp | 49 ++++++++++++---- 4 files changed, 144 insertions(+), 38 deletions(-) diff --git a/src/RISCv64Backend.cpp b/src/RISCv64Backend.cpp index b6a987f..0b2cfaa 100644 --- a/src/RISCv64Backend.cpp +++ b/src/RISCv64Backend.cpp @@ -6,8 +6,6 @@ #include #include -#define DEBUG 0 -#define DEEPDEBUG 0 namespace sysy { // 可用于分配的寄存器 @@ -390,48 +388,118 @@ std::vector> RISCv64CodeGen::build_dag( // 但它本身不应该有 result_vreg,因为不映射到物理寄存器。 create_node(DAGNode::ALLOCA_ADDR, alloca, value_to_node, nodes_storage); } else if (auto store = dynamic_cast(inst)) { - auto store_node = create_node(DAGNode::STORE, store, value_to_node, nodes_storage); // 调用成员函数版 create_node + auto store_node = create_node(DAGNode::STORE, store, value_to_node, nodes_storage); // 获取要存储的值 - DAGNode* val_node = get_operand_node(store->getValue(), value_to_node, nodes_storage); // 传递参数 + DAGNode* val_node = get_operand_node(store->getValue(), value_to_node, nodes_storage); // 获取内存位置的指针 (基地址) Value* ptr_ir = store->getPointer(); - DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage); // 传递参数 + DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage); store_node->operands.push_back(val_node); - store_node->operands.push_back(ptr_node); - val_node->users.push_back(store_node); - ptr_node->users.push_back(store_node); - if (store->getNumIndices()) - if (DEBUG) std::cerr << "处理 StoreInst 的 indices: " << store->getNumIndices() << "\n"; // 调试输出 - for (int i = 0; i < store->getNumIndices(); ++i) { - if (DEBUG) std::cerr << "处理 StoreInst 的 indices: " << i << "\n"; // 调试输出 - Value* index_ir = store->getIndex(i); - DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数 - store_node->operands.push_back(index_node); - index_node->users.push_back(store_node); + // === 修改开始:处理带索引的 StoreInst === + if (store->getNumIndices() > 0) { + if (DEBUG) std::cerr << "处理带索引的 StoreInst: " << store->getNumIndices() << " 个索引\n"; + + // 假设只有一个索引 + Value* index_ir = store->getIndex(0); // 获取索引 IR Value* + DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 索引 DAG 节点 + + // 1. 获取元素大小的 ConstantValue * (例如 4 字节) + // ConstantValue::get 返回裸指针,其生命周期由 IR 框架自身管理(假定是单例或池化)。 + Value* const_4_value_ir = ConstantValue::get(4); + // 为这个常量创建一个 DAGNode + DAGNode* size_node = create_node(DAGNode::CONSTANT, const_4_value_ir, value_to_node, nodes_storage); + + + // 2. 创建一个 BINARY (MUL) 节点来计算字节偏移量 (index * element_size) + // BinaryInst 构造函数是 protected 的,需要通过静态工厂方法创建 + Instruction* dummy_mul_inst_raw_ptr = BinaryInst::create(BinaryInst::kMul, Type::getIntType(), index_ir, const_4_value_ir, bb); + // 将所有权转移到成员变量 temp_instructions_storage + temp_instructions_storage.push_back(std::unique_ptr(dummy_mul_inst_raw_ptr)); // 存储临时的 Instruction + + // 为这个新的 BinaryInst 创建一个 DAGNode,它的类型是 DAGNode::BINARY + DAGNode* byte_offset_node = create_node(DAGNode::BINARY, dummy_mul_inst_raw_ptr, value_to_node, nodes_storage); + + byte_offset_node->operands.push_back(index_node); + byte_offset_node->operands.push_back(size_node); + index_node->users.push_back(byte_offset_node); + size_node->users.push_back(byte_offset_node); + + + // 3. 创建一个 BINARY (ADD) 节点来计算最终地址 (base_address + byte_offset) + // 创建另一个临时的 BinaryInst。 + Instruction* dummy_add_inst_raw_ptr = BinaryInst::create(BinaryInst::kAdd, Type::getIntType(), ptr_ir, dummy_mul_inst_raw_ptr, bb); + temp_instructions_storage.push_back(std::unique_ptr(dummy_add_inst_raw_ptr)); // 存储临时的 Instruction + + // 为这个新的 BinaryInst 创建一个 DAGNode + DAGNode* final_addr_node = create_node(DAGNode::BINARY, dummy_add_inst_raw_ptr, value_to_node, nodes_storage); + + final_addr_node->operands.push_back(ptr_node); + final_addr_node->operands.push_back(byte_offset_node); + ptr_node->users.push_back(final_addr_node); + byte_offset_node->users.push_back(final_addr_node); + + // 现在,STORE 节点的操作数是要存储的值和最终地址 + store_node->operands.push_back(final_addr_node); + final_addr_node->users.push_back(store_node); + + } else { // 原始的非索引 StoreInst 处理 + store_node->operands.push_back(ptr_node); + ptr_node->users.push_back(store_node); } + // === 修改结束 === + } else if (auto load = dynamic_cast(inst)) { - auto load_node = create_node(DAGNode::LOAD, load, value_to_node, nodes_storage); // 调用成员函数版 create_node + auto load_node = create_node(DAGNode::LOAD, load, value_to_node, nodes_storage); // 获取内存位置的指针 (基地址) Value* ptr_ir = load->getPointer(); - DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage); // 传递参数 + DAGNode* ptr_node = get_operand_node(ptr_ir, value_to_node, nodes_storage); - load_node->operands.push_back(ptr_node); - ptr_node->users.push_back(load_node); + // === 修改开始:处理带索引的 LoadInst === + if (load->getNumIndices() > 0) { + // 假设只有一个索引 + Value* index_ir = load->getIndex(0); + DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); - for (int i = 0; i < load->getNumIndices(); ++i) { - Value* index_ir = load->getIndex(i); - DAGNode* index_node = get_operand_node(index_ir, value_to_node, nodes_storage); // 传递参数 - load_node->operands.push_back(index_node); - index_node->users.push_back(load_node); + // 1. 获取元素大小的 ConstantValue * (例如 4 字节) + Value* const_4_value_ir = ConstantValue::get(4); + DAGNode* size_node = create_node(DAGNode::CONSTANT, const_4_value_ir, value_to_node, nodes_storage); + + // 2. 创建一个 BINARY (MUL) 节点来计算字节偏移量 (index * element_size) + Instruction* dummy_mul_inst_raw_ptr = BinaryInst::create(BinaryInst::kMul, Type::getIntType(), index_ir, const_4_value_ir, bb); + temp_instructions_storage.push_back(std::unique_ptr(dummy_mul_inst_raw_ptr)); // 存储临时的 Instruction + + DAGNode* byte_offset_node = create_node(DAGNode::BINARY, dummy_mul_inst_raw_ptr, value_to_node, nodes_storage); + + byte_offset_node->operands.push_back(index_node); + byte_offset_node->operands.push_back(size_node); + index_node->users.push_back(byte_offset_node); + size_node->users.push_back(byte_offset_node); + + // 3. 创建一个 BINARY (ADD) 节点来计算最终地址 (base_address + byte_offset) + Instruction* dummy_add_inst_raw_ptr = BinaryInst::create(BinaryInst::kAdd, Type::getIntType(), ptr_ir, dummy_mul_inst_raw_ptr, bb); + temp_instructions_storage.push_back(std::unique_ptr(dummy_add_inst_raw_ptr)); // 存储临时的 Instruction + + DAGNode* final_addr_node = create_node(DAGNode::BINARY, dummy_add_inst_raw_ptr, value_to_node, nodes_storage); + + final_addr_node->operands.push_back(ptr_node); + final_addr_node->operands.push_back(byte_offset_node); + ptr_node->users.push_back(final_addr_node); + byte_offset_node->users.push_back(final_addr_node); + + // 现在,LOAD 节点的操作数是最终地址 + load_node->operands.push_back(final_addr_node); + final_addr_node->users.push_back(load_node); + + } else { // 原始的非索引 LoadInst 处理 + load_node->operands.push_back(ptr_node); + ptr_node->users.push_back(load_node); } - - // 关联 load_node 的结果到 value_to_node - value_to_node[load] = load_node; // 这里的 value_to_node 是局部变量,OK + // === 修改结束 === } else if (auto bin = dynamic_cast(inst)) { if (value_to_node.count(bin)) continue; // CSE diff --git a/src/RISCv64Backend.h b/src/RISCv64Backend.h index 1762eeb..f60c665 100644 --- a/src/RISCv64Backend.h +++ b/src/RISCv64Backend.h @@ -10,6 +10,9 @@ #include #include // For std::function +extern int DEBUG; +extern int DEEPDEBUG; + namespace sysy { class RISCv64CodeGen { @@ -110,6 +113,8 @@ private: std::map& value_to_node, std::vector>& nodes_storage ); + + std::vector> temp_instructions_storage; // 用于存储 build_dag 中创建的临时 BinaryInst }; } // namespace sysy diff --git a/src/include/IR.h b/src/include/IR.h index dbf12cc..1b4c702 100644 --- a/src/include/IR.h +++ b/src/include/IR.h @@ -883,6 +883,10 @@ public: assert(false); } } ///< 根据指令类型进行二元计算,eval template模板实现 + static BinaryInst* create(Kind kind, Type *type, Value *lhs, Value *rhs, BasicBlock *parent, const std::string &name = "") { + // 后端处理数组访存操作时需要创建计算地址的指令,需要在外部构造 BinaryInst 对象,所以写了个public的方法。 + return new BinaryInst(kind, type, lhs, rhs, parent, name); + } }; // class BinaryInst //! The return statement diff --git a/src/sysyc.cpp b/src/sysyc.cpp index ce14a4c..85ee1ec 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -18,6 +18,9 @@ using namespace antlr4; // #include "LLVMIRGenerator.h" using namespace sysy; +int DEBUG = 0; +int DEEPDEBUG = 0; + static string argStopAfter; static string argInputFile; static bool argFormat = false; @@ -27,7 +30,7 @@ void usage(int code = EXIT_FAILURE) { "Supported options:\n" " -h \tprint help message and exit\n"; " -f \tpretty-format the input file\n"; - " -s {ast,ir,asm,llvmir}\tstop after generating AST/IR/Assembly\n"; + " -s {ast,ir,asm,llvmir,asmd,ird}\tstop after generating AST/IR/Assembly\n"; cerr << msg; exit(code); } @@ -80,10 +83,16 @@ int main(int argc, char **argv) { // visit AST to generate IR SysYIRGenerator generator; generator.visitCompUnit(moduleAST); - if (argStopAfter == "ir") { + if (argStopAfter == "ir" || argStopAfter == "ird") { + if (argStopAfter == "ird") { + DEBUG = 1; + } auto moduleIR = generator.get(); SysYPrinter printer(moduleIR); - printer.printIR(); + if (DEBUG) { + cout << "=== Original IR ===\n"; + printer.printIR(); + } auto builder = generator.getBuilder(); SysYOptPre optPre(moduleIR, builder); optPre.SysYOptimizateAfterIR(); @@ -91,19 +100,35 @@ int main(int argc, char **argv) { cfa.init(); ActiveVarAnalysis ava; ava.init(moduleIR); - printer.printIR(); - - + if (DEBUG) { + cout << "=== After CFA & AVA ===\n"; + printer.printIR(); + } DeadCodeElimination dce(moduleIR, &cfa, &ava); dce.runDCEPipeline(); - + if (DEBUG) { + cout << "=== After 1st DCE ===\n"; + printer.printIR(); + } Mem2Reg mem2reg(moduleIR, builder, &cfa, &ava); mem2reg.mem2regPipeline(); - printer.printIR(); + if (DEBUG) { + cout << "=== After Mem2Reg ===\n"; + printer.printIR(); + } Reg2Mem reg2mem(moduleIR, builder); reg2mem.DeletePhiInst(); - printer.printIR(); + if (DEBUG) { + cout << "=== After Reg2Mem ===\n"; + printer.printIR(); + } dce.runDCEPipeline(); + if (DEBUG) { + cout << "=== After 2nd DCE ===\n"; + printer.printIR(); + } + cout << "=== Final IR ===\n"; + printer.printIR(); return EXIT_SUCCESS; } @@ -111,7 +136,11 @@ int main(int argc, char **argv) { auto module = generator.get(); sysy::RISCv64CodeGen codegen(module); string asmCode = codegen.code_gen(); - if (argStopAfter == "asm") { + if (argStopAfter == "asm" || argStopAfter == "asmd") { + if (argStopAfter == "asmd") { + DEBUG = 1; + DEEPDEBUG = 1; + } cout << asmCode << endl; return EXIT_SUCCESS; }