debugging
This commit is contained in:
182
src/DeadCodeElimination.cpp
Normal file
182
src/DeadCodeElimination.cpp
Normal 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
|
||||
30
src/include/DeadCodeElimination.h
Normal file
30
src/include/DeadCodeElimination.h
Normal 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
|
||||
Reference in New Issue
Block a user