From 0d23475aa1f1524599ccd26b18b0dd8eb519b085 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Wed, 25 Jun 2025 15:33:25 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=AD=BB=E4=BB=A3=E7=A0=81=E5=88=A0=E9=99=A4]?= =?UTF-8?q?:=E4=BF=9D=E8=AF=81=E6=89=A9=E5=B1=95=E6=80=A7=E3=80=81?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=8C=96=E6=9E=84=E5=BB=BA=E6=AD=BB=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=88=A0=E9=99=A4=EF=BC=8C=E5=8C=85=E6=8B=AC=E6=B6=88?= =?UTF-8?q?=E9=99=A4=E6=97=A0=E7=94=A8store,alloca,load,globalval,mem2reg?= =?UTF-8?q?=E5=BC=95=E5=85=A5=E7=9A=84=E6=97=A0=E7=94=A8alloca=E4=BB=A5?= =?UTF-8?q?=E5=8F=8Areg2mem=E5=AF=BC=E8=87=B4=E7=9A=84store-load-store?= =?UTF-8?q?=E5=86=97=E4=BD=99=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CMakeLists.txt | 1 + src/DeadCodeElimination.cpp | 99 ++++++++++++++++++++++++++----- src/include/DeadCodeElimination.h | 11 +++- src/include/IRBuilder.h | 2 +- src/sysyc.cpp | 15 ++++- 5 files changed, 108 insertions(+), 20 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b1a2f00..e7bebb7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(sysyc SysYIRPrinter.cpp SysYIROptPre.cpp SysYIRAnalyser.cpp + DeadCodeElimination.cpp Mem2Reg.cpp Reg2Mem.cpp RISCv32Backend.cpp diff --git a/src/DeadCodeElimination.cpp b/src/DeadCodeElimination.cpp index 80b0022..9abca1c 100644 --- a/src/DeadCodeElimination.cpp +++ b/src/DeadCodeElimination.cpp @@ -19,6 +19,10 @@ void DeadCodeElimination::runDCEPipeline() { } } +// 消除无用存储 消除条件: +// 存储的目标指针(pointer)不是全局变量(!isGlobal(pointer))。 +// 存储的目标指针不是数组参数(!isArr(pointer) 或不在函数参数列表里)。 +// 该指针的所有使用者(uses)仅限 alloca 或 store(即没有 load 或其他指令使用它)。 void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) { for (const auto& block : func->getBasicBlocks()) { auto& instrs = block->getInstructions(); @@ -31,8 +35,8 @@ void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) { auto storeInst = dynamic_cast(inst); auto pointer = storeInst->getPointer(); - if (isGlobal(pointer) || - (isArr(pointer) && + // 如果是全局变量或者是函数的数组参数 + if (isGlobal(pointer) || (isArr(pointer) && std::find(func->getEntryBlock()->getArguments().begin(), func->getEntryBlock()->getArguments().end(), pointer) != func->getEntryBlock()->getArguments().end())) { @@ -40,17 +44,19 @@ void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) { continue; } - bool tag = true; + bool changetag = true; for (auto& use : pointer->getUses()) { + // 依次判断store的指针是否被其他指令使用 auto user = use->getUser(); auto userInst = dynamic_cast(user); + // 如果使用store的指针的指令不是Alloca或Store,则不删除 if (userInst != nullptr && !userInst->isAlloca() && !userInst->isStore()) { - tag = false; + changetag = false; break; } } - if (tag) { + if (changetag) { changed = true; usedelete(storeInst); iter = instrs.erase(iter); @@ -60,7 +66,8 @@ void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) { } } } - +// 消除无用加载 消除条件: +// 该指令的结果未被使用(inst->getUses().empty())。 void DeadCodeElimination::eliminateDeadLoads(Function* func, bool& changed) { for (const auto& block : func->getBasicBlocks()) { auto& instrs = block->getInstructions(); @@ -79,6 +86,9 @@ void DeadCodeElimination::eliminateDeadLoads(Function* func, bool& changed) { } } +// 消除无用加载 消除条件: +// 该 alloca 未被任何指令使用(allocaInst->getUses().empty())。 +// 该 alloca 不是函数的参数(不在 entry 块的参数列表里)。 void DeadCodeElimination::eliminateDeadAllocas(Function* func, bool& changed) { for (const auto& block : func->getBasicBlocks()) { auto& instrs = block->getInstructions(); @@ -99,18 +109,23 @@ void DeadCodeElimination::eliminateDeadAllocas(Function* func, bool& changed) { ++iter; } } - - // for (auto it = func->getIndirectAllocas().begin(); it != func->getIndirectAllocas().end();) { - // auto& allocaInst = *it; - // if (allocaInst->getUses().empty()) { - // changed = true; - // it = func->getIndirectAllocas().erase(it); - // } else { - // ++it; - // } - // } } +void DeadCodeElimination::eliminateDeadIndirectiveAllocas(Function* func, bool& changed) { + // 删除mem2reg时引入的且现在已经没有value使用了的隐式alloca + FunctionAnalysisInfo* funcInfo = pCFA->getFunctionAnalysisInfo(func); + for (auto it = funcInfo->getIndirectAllocas().begin(); it != funcInfo->getIndirectAllocas().end();) { + auto &allocaInst = *it; + if (allocaInst->getUses().empty()) { + changed = true; + it = funcInfo->getIndirectAllocas().erase(it); + } else { + ++it; + } + } +} + +// 该全局变量未被任何指令使用(global->getUses().empty())。 void DeadCodeElimination::eliminateDeadGlobals(bool& changed) { auto& globals = pModule->getGlobals(); for (auto it = globals.begin(); it != globals.end();) { @@ -124,6 +139,10 @@ void DeadCodeElimination::eliminateDeadGlobals(bool& changed) { } } +// 消除冗余加载和存储 消除条件: +// phi 指令的目标指针仅被该 phi 使用(无其他 store/load 使用)。 +// memset 指令的目标指针未被使用(pointer->getUses().empty()) +// store -> load -> store 模式 void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool& changed) { for (const auto& block : func->getBasicBlocks()) { auto& instrs = block->getInstructions(); @@ -140,12 +159,14 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool& break; } } + /// 如果 pointer 仅被该 phi 使用,可以删除 ph if (tag) { changed = true; usedelete(inst); iter = instrs.erase(iter); continue; } + // 数组指令还不完善,不保证memset优化效果 } else if (inst->isMemset()) { auto memsetInst = dynamic_cast(inst); auto pointer = memsetInst->getPointer(); @@ -155,6 +176,52 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool& iter = instrs.erase(iter); continue; } + }else if(inst->isLoad()) { + if (iter != instrs.begin()) { + auto loadInst = dynamic_cast(inst); + auto loadPointer = loadInst->getPointer(); + // TODO:store -> load -> store 模式 + auto prevIter = std::prev(iter); + auto prevInst = prevIter->get(); + if (prevInst->isStore()) { + auto prevStore = dynamic_cast(prevInst); + auto prevStorePointer = prevStore->getPointer(); + auto prevStoreValue = prevStore->getOperand(0); + // 确保前一个 store 不是数组操作 + if (prevStore->getIndices().empty()) { + // 检查后一条指令是否是 store 同一个值 + auto nextIter = std::next(iter); + if (nextIter != instrs.end()) { + auto nextInst = nextIter->get(); + if (nextInst->isStore()) { + auto nextStore = dynamic_cast(nextInst); + auto nextStorePointer = nextStore->getPointer(); + auto nextStoreValue = nextStore->getOperand(0); + // 确保后一个 store 不是数组操作 + if (nextStore->getIndices().empty()) { + // 判断优化条件: + // 1. prevStore 的指针操作数 == load 的指针操作数 + // 2. nextStore 的值操作数 == load 指令本身 + if (prevStorePointer == loadPointer && + nextStoreValue == loadInst) { + // 可以优化直接把prevStorePointer的值存到nextStorePointer + changed = true; + nextStore->setOperand(0, prevStoreValue); + usedelete(loadInst); + iter = instrs.erase(iter); + // 删除 prevStore 这里是不是可以留给删除无用store处理? + // if (prevStore->getUses().empty()) { + // usedelete(prevStore); + // instrs.erase(prevIter); // 删除 prevStore + // } + continue; // 跳过 ++iter,因为已经移动迭代器 + } + } + } + } + } + } + } } ++iter; } diff --git a/src/include/DeadCodeElimination.h b/src/include/DeadCodeElimination.h index 5b127a1..2d614bd 100644 --- a/src/include/DeadCodeElimination.h +++ b/src/include/DeadCodeElimination.h @@ -1,15 +1,21 @@ #pragma once #include "IR.h" - +#include "SysYIRAnalyser.h" namespace sysy { class DeadCodeElimination { private: Module *pModule; + ControlFlowAnalysis *pCFA; // 控制流分析指针 + ActiveVarAnalysis *pAVA; // 活跃变量分析指针 + DataFlowAnalysisUtils dataFlowAnalysisUtils; // 数据流分析工具类 public: - explicit DeadCodeElimination(Module *pMoudle) : pModule(pMoudle) {} // 初始化函数 + explicit DeadCodeElimination(Module *pMoudle, + ControlFlowAnalysis *pCFA = nullptr, + ActiveVarAnalysis *pAVA = nullptr) + : pModule(pMoudle), pCFA(pCFA), pAVA(pAVA), dataFlowAnalysisUtils() {} // 构造函数 // TODO:根据参数传入的passes来运行不同的死代码删除流程 // void runDCEPipeline(const std::vector& passes = { @@ -21,6 +27,7 @@ class DeadCodeElimination { void eliminateDeadLoads(Function* func, bool& changed); // 消除无用加载 void eliminateDeadAllocas(Function* func, bool& changed); // 消除无用内存分配 void eliminateDeadGlobals(bool& changed); // 消除无用全局变量 + void eliminateDeadIndirectiveAllocas(Function* func, bool& changed); // 消除无用间接内存分配(phi节点) void eliminateDeadRedundantLoadStore(Function* func, bool& changed); // 消除冗余加载和存储 bool isGlobal(Value *val); bool isArr(Value *val); diff --git a/src/include/IRBuilder.h b/src/include/IRBuilder.h index 088427f..aab9a1d 100644 --- a/src/include/IRBuilder.h +++ b/src/include/IRBuilder.h @@ -263,7 +263,7 @@ class IRBuilder { auto inst = new AllocaInst(type, dims, parent, name); assert(inst); return inst; - } ///< 创建不插入指令列表的分配指令 + } ///< 创建不插入指令列表的分配指令[仅用于phi指令] LoadInst * createLoadInst(Value *pointer, const std::vector &indices = {}, const std::string &name = "") { std::string newName; if (name.empty()) { diff --git a/src/sysyc.cpp b/src/sysyc.cpp index acb553e..f21fb49 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -11,6 +11,7 @@ using namespace antlr4; #include "SysYIRPrinter.h" #include "SysYIROptPre.h" #include "SysYIRAnalyser.h" +#include "DeadCodeElimination.h" #include "Mem2Reg.h" #include "Reg2Mem.h" // #include "LLVMIRGenerator.h" @@ -86,12 +87,24 @@ int main(int argc, char **argv) { auto builder = generator.getBuilder(); SysYOptPre optPre(moduleIR, builder); optPre.SysYOptimizateAfterIR(); - Mem2Reg mem2reg(moduleIR, builder); + ControlFlowAnalysis cfa(moduleIR); + cfa.init(); + ActiveVarAnalysis ava; + ava.init(moduleIR); + printer.printIR(); + + + DeadCodeElimination dce(moduleIR, &cfa, &ava); + dce.runDCEPipeline(); + + Mem2Reg mem2reg(moduleIR, builder, &cfa, &ava); mem2reg.mem2regPipeline(); printer.printIR(); Reg2Mem reg2mem(moduleIR, builder); reg2mem.DeletePhiInst(); printer.printIR(); + dce.runDCEPipeline(); + printer.printIR(); return EXIT_SUCCESS; } return EXIT_SUCCESS;