debugging

This commit is contained in:
rain2133
2025-06-25 14:00:27 +08:00
parent 050113d31d
commit 1e06c5a446
2 changed files with 212 additions and 0 deletions

182
src/DeadCodeElimination.cpp Normal file
View File

@@ -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<StoreInst*>(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<Instruction*>(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<AllocaInst*>(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<PhiInst*>(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<MemsetInst*>(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<GlobalValue *>(val);
return gval != nullptr;
}
bool DeadCodeElimination::isArr(Value *val){
auto aval = dynamic_cast<AllocaInst *>(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

View File

@@ -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<std::string>& 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