From 050113d31da3c05e38c1bf7235ba800a61939561 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Wed, 25 Jun 2025 13:17:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Reg2Mem,=E4=BD=86=E6=98=AF?= =?UTF-8?q?=E4=BC=9A=E7=94=9F=E6=88=90=E6=AD=BB=E5=AD=98=E5=82=A8=E6=8C=87?= =?UTF-8?q?=E4=BB=A4=EF=BC=8C=E9=9C=80=E8=A6=81=E6=AD=BB=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=94=AF=E6=8C=81=E8=AF=86=E5=88=AB=E6=AD=BB?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CMakeLists.txt | 1 + src/Mem2Reg.cpp | 17 ++---- src/Reg2Mem.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++ src/include/Reg2Mem.h | 23 ++++++++ src/sysyc.cpp | 4 ++ 5 files changed, 161 insertions(+), 13 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1251e4f..b1a2f00 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,7 @@ add_executable(sysyc SysYIROptPre.cpp SysYIRAnalyser.cpp Mem2Reg.cpp + Reg2Mem.cpp RISCv32Backend.cpp ) target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/src/Mem2Reg.cpp b/src/Mem2Reg.cpp index 4991d96..968e4f3 100644 --- a/src/Mem2Reg.cpp +++ b/src/Mem2Reg.cpp @@ -570,7 +570,7 @@ auto Mem2Reg::preOptimize3() -> void { } /** - * @brief 为所有变量的定义块集合的迭代支配边界插入phi结点(剪枝版) + * @brief 为所有变量的定义块集合的迭代支配边界插入phi结点 * * insertPhi是mem2reg的核心之一,这里是对所有变量的迭代支配边界的phi结点插入,无参数也无返回值; * 同样跳过对数组和全局变量的处理,因为这些变量不会被mem2reg优化,刚好这里在计算value2DefBlocks时已经跳过了,所以不需要再显式处理了; @@ -796,10 +796,7 @@ auto Mem2Reg::getPredIndex(BasicBlock *n, BasicBlock *s) -> int { } /** - * @brief 判断一个value是不是全局变量 - * - * @param [in] val 一个value - * @return 返回true表示是全局变量,返回false表示不是 + * 判断一个value是不是全局变量 */ auto Mem2Reg::isGlobal(Value *val) -> bool { auto gval = dynamic_cast(val); @@ -807,10 +804,7 @@ auto Mem2Reg::isGlobal(Value *val) -> bool { } /** - * @brief 判断一个value是不是数组 - * - * @param [in] val 一个value - * @return 返回true表示是数组,返回false表示不是 + * 判断一个value是不是数组 */ auto Mem2Reg::isArr(Value *val) -> bool { auto aval = dynamic_cast(val); @@ -818,10 +812,7 @@ auto Mem2Reg::isArr(Value *val) -> bool { } /** - * @brief 删除一个指令的operand对应的value的该条use - * - * @param [in] inst 一条指令 - * @return 无返回值 + * 删除一个指令的operand对应的value的该条use */ auto Mem2Reg::usedelete(Instruction *instr) -> void { for (auto &use : instr->getOperands()) { diff --git a/src/Reg2Mem.cpp b/src/Reg2Mem.cpp index e69de29..d44d1c8 100644 --- a/src/Reg2Mem.cpp +++ b/src/Reg2Mem.cpp @@ -0,0 +1,129 @@ +#include "Reg2Mem.h" +#include +#include +#include +#include + +namespace sysy { + +/** + * 删除phi节点 + * 删除phi节点后可能会生成冗余存储代码 + */ +void Reg2Mem::DeletePhiInst(){ + auto &functions = pModule->getFunctions(); + for (auto &function : functions) { + auto basicBlocks = function.second->getBasicBlocks(); + for (auto &basicBlock : basicBlocks) { + + for (auto iter = basicBlock->begin(); iter != basicBlock->end();) { + auto &instruction = *iter; + if (instruction->isPhi()) { + auto predBlocks = basicBlock->getPredecessors(); + // 寻找源和目的 + // 目的就是phi指令的第一个操作数 + // 源就是phi指令的后续操作数 + auto destination = instruction->getOperand(0); + int predBlockindex = 0; + for (auto &predBlock : predBlocks) { + ++predBlockindex; + // 判断前驱块儿只有一个后继还是多个后继 + // 如果有多个 + auto source = instruction->getOperand(predBlockindex); + if (source == destination) { + continue; + } + // std::cout << predBlock->getNumSuccessors() << std::endl; + if (predBlock->getNumSuccessors() > 1) { + // 创建一个basicblock + auto newbasicBlock = function.second->addBasicBlock(); + std::stringstream ss; + ss << " phidel.L" << pBuilder->getLabelIndex(); + newbasicBlock->setName(ss.str()); + ss.str(""); + // // 修改前驱后继关系 + basicBlock->replacePredecessor(predBlock, newbasicBlock); + // predBlock = newbasicBlock; + newbasicBlock->addPredecessor(predBlock); + newbasicBlock->addSuccessor(basicBlock.get()); + predBlock->removeSuccessor(basicBlock.get()); + predBlock->addSuccessor(newbasicBlock); + // std::cout << "the block name is " << basicBlock->getName() << std::endl; + // for (auto pb : basicBlock->getPredecessors()) { + // // newbasicBlock->addPredecessor(pb); + // std::cout << pb->getName() << std::endl; + // } + // sysy::BasicBlock::conectBlocks(newbasicBlock, static_cast(basicBlock.get())); + // 若后为跳转指令,应该修改跳转指令所到达的位置 + auto thelastinst = predBlock->end(); + (--thelastinst); + + if (thelastinst->get()->isConditional() || thelastinst->get()->isUnconditional()) { // 如果是跳转指令 + auto opnum = thelastinst->get()->getNumOperands(); + for (size_t i = 0; i < opnum; i++) { + if (thelastinst->get()->getOperand(i) == basicBlock.get()) { + thelastinst->get()->replaceOperand(i, newbasicBlock); + } + } + } + // 在新块中插入store指令 + pBuilder->setPosition(newbasicBlock, newbasicBlock->end()); + // pBuilder->createStoreInst(source, destination); + if (source->isInt() || source->isFloat()) { + pBuilder->createStoreInst(source, destination); + } else { + auto loadInst = pBuilder->createLoadInst(source); + pBuilder->createStoreInst(loadInst, destination); + } + // pBuilder->createMoveInst(Instruction::kMove, destination->getType(), destination, source, + // newbasicBlock); + pBuilder->setPosition(newbasicBlock, newbasicBlock->end()); + pBuilder->createUncondBrInst(basicBlock.get(), {}); + } else { + // 如果前驱块只有一个后继 + auto thelastinst = predBlock->end(); + (--thelastinst); + // std::cout << predBlock->getName() << std::endl; + // std::cout << thelastinst->get() << std::endl; + // std::cout << "First point 11 " << std::endl; + if (thelastinst->get()->isConditional() || thelastinst->get()->isUnconditional()) { + // 在跳转语句前insert st指令 + pBuilder->setPosition(predBlock, thelastinst); + } else { + pBuilder->setPosition(predBlock, predBlock->end()); + } + + if (source->isInt() || source->isFloat()) { + pBuilder->createStoreInst(source, destination); + } else { + auto loadInst = pBuilder->createLoadInst(source); + pBuilder->createStoreInst(loadInst, destination); + } + } + } + // 删除phi指令 + auto &instructions = basicBlock->getInstructions(); + usedelete(iter->get()); + iter = instructions.erase(iter); + if (basicBlock->getNumInstructions() == 0) { + if (basicBlock->getNumSuccessors() == 1) { + pBuilder->setPosition(basicBlock.get(), basicBlock->end()); + pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); + } + } + } else { + break; + } + } + } + } +} + +void Reg2Mem::usedelete(Instruction *instr) { + for (auto &use : instr->getOperands()) { + auto val = use->getValue(); + val->removeUse(use); + } +} + +} // namespace sysy diff --git a/src/include/Reg2Mem.h b/src/include/Reg2Mem.h index e69de29..6249d71 100644 --- a/src/include/Reg2Mem.h +++ b/src/include/Reg2Mem.h @@ -0,0 +1,23 @@ +#pragma once + +#include "IR.h" +#include "IRBuilder.h" + +namespace sysy { +/** + * Reg2Mem(后端未做phi指令翻译) + */ +class Reg2Mem { +private: + Module *pModule; + IRBuilder *pBuilder; + +public: + Reg2Mem(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {} + + void DeletePhiInst(); + // 删除UD关系, 因为删除了phi指令会修改ud关系 + void usedelete(Instruction *instr); +}; + +} // namespace sysy \ No newline at end of file diff --git a/src/sysyc.cpp b/src/sysyc.cpp index f2f68a3..acb553e 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -12,6 +12,7 @@ using namespace antlr4; #include "SysYIROptPre.h" #include "SysYIRAnalyser.h" #include "Mem2Reg.h" +#include "Reg2Mem.h" // #include "LLVMIRGenerator.h" using namespace sysy; @@ -88,6 +89,9 @@ int main(int argc, char **argv) { Mem2Reg mem2reg(moduleIR, builder); mem2reg.mem2regPipeline(); printer.printIR(); + Reg2Mem reg2mem(moduleIR, builder); + reg2mem.DeletePhiInst(); + printer.printIR(); return EXIT_SUCCESS; } return EXIT_SUCCESS;