From 1e06c5a446818530485cd573ea62cf0d00af807e Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Wed, 25 Jun 2025 14:00:27 +0800 Subject: [PATCH] debugging --- src/DeadCodeElimination.cpp | 182 ++++++++++++++++++++++++++++++ src/include/DeadCodeElimination.h | 30 +++++ 2 files changed, 212 insertions(+) create mode 100644 src/DeadCodeElimination.cpp create mode 100644 src/include/DeadCodeElimination.h diff --git a/src/DeadCodeElimination.cpp b/src/DeadCodeElimination.cpp new file mode 100644 index 0000000..80b0022 --- /dev/null +++ b/src/DeadCodeElimination.cpp @@ -0,0 +1,182 @@ +#include "DeadCodeElimination.h" + +namespace sysy { + + +void DeadCodeElimination::runDCEPipeline() { + const auto& functions = pModule->getFunctions(); + for (const auto& function : functions) { + const auto& func = function.second; + bool changed = true; + while (changed) { + changed = false; + eliminateDeadStores(func.get(), changed); + eliminateDeadLoads(func.get(), changed); + eliminateDeadAllocas(func.get(), changed); + eliminateDeadRedundantLoadStore(func.get(), changed); + eliminateDeadGlobals(changed); + } + } +} + +void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) { + for (const auto& block : func->getBasicBlocks()) { + auto& instrs = block->getInstructions(); + for (auto iter = instrs.begin(); iter != instrs.end();) { + auto inst = iter->get(); + if (!inst->isStore()) { + ++iter; + continue; + } + + auto storeInst = dynamic_cast(inst); + auto pointer = storeInst->getPointer(); + if (isGlobal(pointer) || + (isArr(pointer) && + std::find(func->getEntryBlock()->getArguments().begin(), + func->getEntryBlock()->getArguments().end(), + pointer) != func->getEntryBlock()->getArguments().end())) { + ++iter; + continue; + } + + bool tag = true; + for (auto& use : pointer->getUses()) { + auto user = use->getUser(); + auto userInst = dynamic_cast(user); + if (userInst != nullptr && !userInst->isAlloca() && !userInst->isStore()) { + tag = false; + break; + } + } + + if (tag) { + changed = true; + usedelete(storeInst); + iter = instrs.erase(iter); + } else { + ++iter; + } + } + } +} + +void DeadCodeElimination::eliminateDeadLoads(Function* func, bool& changed) { + for (const auto& block : func->getBasicBlocks()) { + auto& instrs = block->getInstructions(); + for (auto iter = instrs.begin(); iter != instrs.end();) { + auto inst = iter->get(); + if (inst->isBinary() || inst->isUnary() || inst->isLoad()) { + if (inst->getUses().empty()) { + changed = true; + usedelete(inst); + iter = instrs.erase(iter); + continue; + } + } + ++iter; + } + } +} + +void DeadCodeElimination::eliminateDeadAllocas(Function* func, bool& changed) { + for (const auto& block : func->getBasicBlocks()) { + auto& instrs = block->getInstructions(); + for (auto iter = instrs.begin(); iter != instrs.end();) { + auto inst = iter->get(); + if (inst->isAlloca()) { + auto allocaInst = dynamic_cast(inst); + if (allocaInst->getUses().empty() && + std::find(func->getEntryBlock()->getArguments().begin(), + func->getEntryBlock()->getArguments().end(), + allocaInst) == func->getEntryBlock()->getArguments().end()) { + changed = true; + usedelete(inst); + iter = instrs.erase(iter); + continue; + } + } + ++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::eliminateDeadGlobals(bool& changed) { + auto& globals = pModule->getGlobals(); + for (auto it = globals.begin(); it != globals.end();) { + auto& global = *it; + if (global->getUses().empty()) { + changed = true; + it = globals.erase(it); + } else { + ++it; + } + } +} + +void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool& changed) { + for (const auto& block : func->getBasicBlocks()) { + auto& instrs = block->getInstructions(); + for (auto iter = instrs.begin(); iter != instrs.end();) { + auto inst = iter->get(); + if (inst->isPhi()) { + auto phiInst = dynamic_cast(inst); + auto pointer = phiInst->getPointer(); + bool tag = true; + for (const auto& use : pointer->getUses()) { + auto user = use->getUser(); + if (user != inst) { + tag = false; + break; + } + } + if (tag) { + changed = true; + usedelete(inst); + iter = instrs.erase(iter); + continue; + } + } else if (inst->isMemset()) { + auto memsetInst = dynamic_cast(inst); + auto pointer = memsetInst->getPointer(); + if (pointer->getUses().empty()) { + changed = true; + usedelete(inst); + iter = instrs.erase(iter); + continue; + } + } + ++iter; + } + } +} + + +bool DeadCodeElimination::isGlobal(Value *val){ + auto gval = dynamic_cast(val); + return gval != nullptr; +} + +bool DeadCodeElimination::isArr(Value *val){ + auto aval = dynamic_cast(val); + return aval != nullptr && aval->getNumDims() != 0; +} + +void DeadCodeElimination::usedelete(Instruction *instr){ + for (auto &use1 : instr->getOperands()) { + auto val1 = use1->getValue(); + val1->removeUse(use1); + } +} + +} // namespace sysy \ No newline at end of file diff --git a/src/include/DeadCodeElimination.h b/src/include/DeadCodeElimination.h new file mode 100644 index 0000000..5b127a1 --- /dev/null +++ b/src/include/DeadCodeElimination.h @@ -0,0 +1,30 @@ +#pragma once + +#include "IR.h" + +namespace sysy { + +class DeadCodeElimination { + private: + Module *pModule; + + public: + explicit DeadCodeElimination(Module *pMoudle) : pModule(pMoudle) {} // 初始化函数 + + // TODO:根据参数传入的passes来运行不同的死代码删除流程 + // void runDCEPipeline(const std::vector& passes = { + // "dead-store", "redundant-load-store", "dead-load", "dead-alloca", "dead-global" + // }); + void runDCEPipeline(); // 运行死代码删除 + + void eliminateDeadStores(Function* func, bool& changed); // 消除无用存储 + void eliminateDeadLoads(Function* func, bool& changed); // 消除无用加载 + void eliminateDeadAllocas(Function* func, bool& changed); // 消除无用内存分配 + void eliminateDeadGlobals(bool& changed); // 消除无用全局变量 + void eliminateDeadRedundantLoadStore(Function* func, bool& changed); // 消除冗余加载和存储 + bool isGlobal(Value *val); + bool isArr(Value *val); + void usedelete(Instruction *instr); + +}; +} // namespace sysy