[SysYIROptUtils]增加通用优化工具类,修改相关代码

This commit is contained in:
rain2133
2025-07-16 14:21:00 +08:00
parent f4d599a567
commit 5a6cfbee1e
9 changed files with 77 additions and 106 deletions

View File

@ -37,7 +37,7 @@ void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) {
auto storeInst = dynamic_cast<StoreInst*>(inst); auto storeInst = dynamic_cast<StoreInst*>(inst);
auto pointer = storeInst->getPointer(); auto pointer = storeInst->getPointer();
// 如果是全局变量或者是函数的数组参数 // 如果是全局变量或者是函数的数组参数
if (isGlobal(pointer) || (isArr(pointer) && if (SysYIROptUtils::isGlobal(pointer) || (SysYIROptUtils::isArr(pointer) &&
std::find(func->getEntryBlock()->getArguments().begin(), std::find(func->getEntryBlock()->getArguments().begin(),
func->getEntryBlock()->getArguments().end(), func->getEntryBlock()->getArguments().end(),
pointer) != func->getEntryBlock()->getArguments().end())) { pointer) != func->getEntryBlock()->getArguments().end())) {
@ -63,7 +63,7 @@ void DeadCodeElimination::eliminateDeadStores(Function* func, bool& changed) {
std::cout << "=== Dead Store Found ===\n"; std::cout << "=== Dead Store Found ===\n";
SysYPrinter::printInst(storeInst); SysYPrinter::printInst(storeInst);
} }
usedelete(storeInst); SysYIROptUtils::usedelete(storeInst);
iter = instrs.erase(iter); iter = instrs.erase(iter);
} else { } else {
++iter; ++iter;
@ -85,7 +85,7 @@ void DeadCodeElimination::eliminateDeadLoads(Function* func, bool& changed) {
std::cout << "=== Dead Load Binary Unary Found ===\n"; std::cout << "=== Dead Load Binary Unary Found ===\n";
SysYPrinter::printInst(inst); SysYPrinter::printInst(inst);
} }
usedelete(inst); SysYIROptUtils::usedelete(inst);
iter = instrs.erase(iter); iter = instrs.erase(iter);
continue; continue;
} }
@ -114,7 +114,7 @@ void DeadCodeElimination::eliminateDeadAllocas(Function* func, bool& changed) {
std::cout << "=== Dead Alloca Found ===\n"; std::cout << "=== Dead Alloca Found ===\n";
SysYPrinter::printInst(inst); SysYPrinter::printInst(inst);
} }
usedelete(inst); SysYIROptUtils::usedelete(inst);
iter = instrs.erase(iter); iter = instrs.erase(iter);
continue; continue;
} }
@ -183,7 +183,7 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
/// 如果 pointer 仅被该 phi 使用,可以删除 ph /// 如果 pointer 仅被该 phi 使用,可以删除 ph
if (tag) { if (tag) {
changed = true; changed = true;
usedelete(inst); SysYIROptUtils::usedelete(inst);
iter = instrs.erase(iter); iter = instrs.erase(iter);
continue; continue;
} }
@ -193,7 +193,7 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
auto pointer = memsetInst->getPointer(); auto pointer = memsetInst->getPointer();
if (pointer->getUses().empty()) { if (pointer->getUses().empty()) {
changed = true; changed = true;
usedelete(inst); SysYIROptUtils::usedelete(inst);
iter = instrs.erase(iter); iter = instrs.erase(iter);
continue; continue;
} }
@ -234,7 +234,7 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
SysYPrinter::printInst(loadInst); SysYPrinter::printInst(loadInst);
SysYPrinter::printInst(nextStore); SysYPrinter::printInst(nextStore);
} }
usedelete(loadInst); SysYIROptUtils::usedelete(loadInst);
iter = instrs.erase(iter); iter = instrs.erase(iter);
// 删除 prevStore 这里是不是可以留给删除无用store处理 // 删除 prevStore 这里是不是可以留给删除无用store处理
// if (prevStore->getUses().empty()) { // if (prevStore->getUses().empty()) {
@ -256,21 +256,4 @@ void DeadCodeElimination::eliminateDeadRedundantLoadStore(Function* func, bool&
} }
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 } // namespace sysy

View File

@ -75,7 +75,7 @@ auto Mem2Reg::computeValue2Blocks() -> void {
// std::cout << std::endl; // std::cout << std::endl;
if (instr->isAlloca()) { if (instr->isAlloca()) {
if (!(isArr(instr.get()) || isGlobal(instr.get()))) { if (!(SysYIROptUtils::isArr(instr.get()) || SysYIROptUtils::isGlobal(instr.get()))) {
// std::cout << " Found alloca: "; // std::cout << " Found alloca: ";
// printer.printInst(instr.get()); // printer.printInst(instr.get());
// std::cout << " -> Adding to allocBlocks" << std::endl; // std::cout << " -> Adding to allocBlocks" << std::endl;
@ -92,7 +92,7 @@ auto Mem2Reg::computeValue2Blocks() -> void {
// std::cout << " Store target: "; // std::cout << " Store target: ";
// printer.printInst(dynamic_cast<Instruction *>(val)); // printer.printInst(dynamic_cast<Instruction *>(val));
if (!(isArr(val) || isGlobal(val))) { if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
// std::cout << " Adding store to defBlocks for value: "; // std::cout << " Adding store to defBlocks for value: ";
// printer.printInst(dynamic_cast<Instruction *>(instr.get())); // printer.printInst(dynamic_cast<Instruction *>(instr.get()));
// std::cout << std::endl; // std::cout << std::endl;
@ -108,7 +108,7 @@ auto Mem2Reg::computeValue2Blocks() -> void {
// printer.printInst(dynamic_cast<Instruction *>(val)); // printer.printInst(dynamic_cast<Instruction *>(val));
// std::cout << std::endl; // std::cout << std::endl;
if (!(isArr(val) || isGlobal(val))) { if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
// std::cout << " Adding load to useBlocks for value: "; // std::cout << " Adding load to useBlocks for value: ";
// printer.printInst(dynamic_cast<Instruction *>(val)); // printer.printInst(dynamic_cast<Instruction *>(val));
// std::cout << std::endl; // std::cout << std::endl;
@ -199,7 +199,7 @@ auto Mem2Reg::cascade(Instruction *instr, bool &changed, Function *func, BasicBl
auto tofind = auto tofind =
std::find_if(instrs.begin(), instrs.end(), [&top](const auto &instr) { return instr.get() == top; }); std::find_if(instrs.begin(), instrs.end(), [&top](const auto &instr) { return instr.get() == top; });
assert(tofind != instrs.end()); assert(tofind != instrs.end());
usedelete(tofind->get()); SysYIROptUtils::usedelete(tofind->get());
instrs.erase(tofind); instrs.erase(tofind);
} }
} }
@ -291,7 +291,7 @@ auto Mem2Reg::preOptimize1() -> void {
continue; continue;
} }
usedelete(tofind->get()); SysYIROptUtils::usedelete(tofind->get());
bb->getInstructions().erase(tofind); bb->getInstructions().erase(tofind);
iter = vToAllocB.erase(iter); iter = vToAllocB.erase(iter);
} else { } else {
@ -334,7 +334,7 @@ auto Mem2Reg::preOptimize1() -> void {
std::cout << std::endl; std::cout << std::endl;
auto valUsedByStore = dynamic_cast<Instruction *>((*it)->getOperand(0)); auto valUsedByStore = dynamic_cast<Instruction *>((*it)->getOperand(0));
usedelete(it->get()); SysYIROptUtils::usedelete(it->get());
if (valUsedByStore != nullptr && if (valUsedByStore != nullptr &&
valUsedByStore->getUses().size() == 1 && valUsedByStore->getUses().size() == 1 &&
@ -370,7 +370,7 @@ auto Mem2Reg::preOptimize1() -> void {
return instr.get() == val; return instr.get() == val;
}); });
if (tofind != bb->getInstructions().end()) { if (tofind != bb->getInstructions().end()) {
usedelete(tofind->get()); SysYIROptUtils::usedelete(tofind->get());
bb->getInstructions().erase(tofind); bb->getInstructions().erase(tofind);
} else { } else {
std::cerr << "ERROR: Alloca not found in BB!" << std::endl; std::cerr << "ERROR: Alloca not found in BB!" << std::endl;
@ -423,7 +423,7 @@ auto Mem2Reg::preOptimize2() -> void {
for (auto curit = std::next(it); curit != instrs.end();) { for (auto curit = std::next(it); curit != instrs.end();) {
if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) { if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) {
curit->get()->replaceAllUsesWith(propogationVal); curit->get()->replaceAllUsesWith(propogationVal);
usedelete(curit->get()); SysYIROptUtils::usedelete(curit->get());
curit = instrs.erase(curit); curit = instrs.erase(curit);
funcInfo->removeValue2UseBlock(val, block); funcInfo->removeValue2UseBlock(val, block);
} else { } else {
@ -454,7 +454,7 @@ auto Mem2Reg::preOptimize2() -> void {
for (auto childIter = childInstrs.begin(); childIter != childInstrs.end();) { for (auto childIter = childInstrs.begin(); childIter != childInstrs.end();) {
if ((*childIter)->isLoad() && (*childIter)->getOperand(0) == val) { if ((*childIter)->isLoad() && (*childIter)->getOperand(0) == val) {
childIter->get()->replaceAllUsesWith(propogationVal); childIter->get()->replaceAllUsesWith(propogationVal);
usedelete(childIter->get()); SysYIROptUtils::usedelete(childIter->get());
childIter = childInstrs.erase(childIter); childIter = childInstrs.erase(childIter);
funcInfo->removeValue2UseBlock(val, child); funcInfo->removeValue2UseBlock(val, child);
} else { } else {
@ -465,7 +465,7 @@ auto Mem2Reg::preOptimize2() -> void {
// 如果对该val的所有load均替换掉了那么对于该val的defining block中的最后一个define也可以删除了 // 如果对该val的所有load均替换掉了那么对于该val的defining block中的最后一个define也可以删除了
// 同时该块中前面对于该val的define也变成死代码了可调用preOptimize1进行删除 // 同时该块中前面对于该val的define也变成死代码了可调用preOptimize1进行删除
if (funcInfo->getUseBlocksByValue(val).empty()) { if (funcInfo->getUseBlocksByValue(val).empty()) {
usedelete(it->get()); SysYIROptUtils::usedelete(it->get());
instrs.erase(it); instrs.erase(it);
auto change = funcInfo->removeValue2DefBlock(val, block); auto change = funcInfo->removeValue2DefBlock(val, block);
if (change) { if (change) {
@ -476,7 +476,7 @@ auto Mem2Reg::preOptimize2() -> void {
assert(bb != nullptr); assert(bb != nullptr);
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(), auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
[val](const auto &instr) { return instr.get() == val; }); [val](const auto &instr) { return instr.get() == val; });
usedelete(tofind->get()); SysYIROptUtils::usedelete(tofind->get());
bb->getInstructions().erase(tofind); bb->getInstructions().erase(tofind);
funcInfo->removeValue2AllocBlock(val); funcInfo->removeValue2AllocBlock(val);
} }
@ -529,7 +529,7 @@ auto Mem2Reg::preOptimize3() -> void {
for (auto curit = std::next(it); curit != last;) { for (auto curit = std::next(it); curit != last;) {
if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) { if ((*curit)->isLoad() && (*curit)->getOperand(0) == val) {
curit->get()->replaceAllUsesWith(propogationVal); curit->get()->replaceAllUsesWith(propogationVal);
usedelete(curit->get()); SysYIROptUtils::usedelete(curit->get());
curit = instrs.erase(curit); curit = instrs.erase(curit);
funcInfo->removeValue2UseBlock(val, block); funcInfo->removeValue2UseBlock(val, block);
} else { } else {
@ -541,14 +541,14 @@ auto Mem2Reg::preOptimize3() -> void {
[val](const auto &instr) { return instr == val; }) != [val](const auto &instr) { return instr == val; }) !=
func->getEntryBlock()->getArguments().end()) && func->getEntryBlock()->getArguments().end()) &&
last == instrs.end()) { last == instrs.end()) {
usedelete(it->get()); SysYIROptUtils::usedelete(it->get());
it = instrs.erase(it); it = instrs.erase(it);
if (funcInfo->removeValue2DefBlock(val, block)) { if (funcInfo->removeValue2DefBlock(val, block)) {
auto bb = funcInfo->getAllocBlockByValue(val); auto bb = funcInfo->getAllocBlockByValue(val);
if (bb != nullptr) { if (bb != nullptr) {
auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(), auto tofind = std::find_if(bb->getInstructions().begin(), bb->getInstructions().end(),
[val](const auto &instr) { return instr.get() == val; }); [val](const auto &instr) { return instr.get() == val; });
usedelete(tofind->get()); SysYIROptUtils::usedelete(tofind->get());
bb->getInstructions().erase(tofind); bb->getInstructions().erase(tofind);
funcInfo->removeValue2AllocBlock(val); funcInfo->removeValue2AllocBlock(val);
} }
@ -610,7 +610,7 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
// 对于load指令变量用最新的那个 // 对于load指令变量用最新的那个
if (instr->isLoad()) { if (instr->isLoad()) {
auto val = instr->getOperand(0); auto val = instr->getOperand(0);
if (!(isArr(val) || isGlobal(val))) { if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
if (!stacks[val].empty()) { if (!stacks[val].empty()) {
instr->replaceOperand(0, stacks[val].top()); instr->replaceOperand(0, stacks[val].top());
} }
@ -621,7 +621,7 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
if (instr->isAlloca()) { if (instr->isAlloca()) {
// alloca指令名字不改了命名就按xx_1x_2...来就行 // alloca指令名字不改了命名就按xx_1x_2...来就行
auto val = instr; auto val = instr;
if (!(isArr(val) || isGlobal(val))) { if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
++valPop[val]; ++valPop[val];
stacks[val].push(val); stacks[val].push(val);
++count[val]; ++count[val];
@ -629,11 +629,11 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
} else if (instr->isPhi()) { } else if (instr->isPhi()) {
// Phi指令也是一条特殊的define指令 // Phi指令也是一条特殊的define指令
auto val = dynamic_cast<PhiInst *>(instr)->getMapVal(); auto val = dynamic_cast<PhiInst *>(instr)->getMapVal();
if (!(isArr(val) || isGlobal(val))) { if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
auto i = count[val]; auto i = count[val];
if (i == 0) { if (i == 0) {
// 对还未alloca就有phi的指令的处理直接删除 // 对还未alloca就有phi的指令的处理直接删除
usedelete(iter->get()); SysYIROptUtils::usedelete(iter->get());
iter = instrs.erase(iter); iter = instrs.erase(iter);
continue; continue;
} }
@ -649,7 +649,7 @@ auto Mem2Reg::rename(BasicBlock *block, std::unordered_map<Value *, int> &count,
} else { } else {
// store指令看operand的名字我们的实现是规定变量在operand的第二位用一个新的alloca x_i代替 // store指令看operand的名字我们的实现是规定变量在operand的第二位用一个新的alloca x_i代替
auto val = instr->getOperand(1); auto val = instr->getOperand(1);
if (!(isArr(val) || isGlobal(val))) { if (!(SysYIROptUtils::isArr(val) || SysYIROptUtils::isGlobal(val))) {
auto i = count[val]; auto i = count[val];
auto newname = dynamic_cast<Instruction *>(val)->getName() + "_" + std::to_string(i); auto newname = dynamic_cast<Instruction *>(val)->getName() + "_" + std::to_string(i);
auto newalloca = pBuilder->createAllocaInstWithoutInsert(val->getType(), {}, block, newname); auto newalloca = pBuilder->createAllocaInstWithoutInsert(val->getType(), {}, block, newname);
@ -773,29 +773,4 @@ auto Mem2Reg::getPredIndex(BasicBlock *n, BasicBlock *s) -> int {
return index; return index;
} }
/**
* 判断一个value是不是全局变量
*/
auto Mem2Reg::isGlobal(Value *val) -> bool {
auto gval = dynamic_cast<GlobalValue *>(val);
return gval != nullptr;
}
/**
* 判断一个value是不是数组
*/
auto Mem2Reg::isArr(Value *val) -> bool {
auto aval = dynamic_cast<AllocaInst *>(val);
return aval != nullptr && aval->getNumDims() != 0;
}
/**
* 删除一个指令的operand对应的value的该条use
*/
auto Mem2Reg::usedelete(Instruction *instr) -> void {
for (auto &use : instr->getOperands()) {
auto val = use->getValue();
val->removeUse(use);
}
}
} // namespace sysy } // namespace sysy

View File

@ -103,7 +103,7 @@ void Reg2Mem::DeletePhiInst(){
} }
// 删除phi指令 // 删除phi指令
auto &instructions = basicBlock->getInstructions(); auto &instructions = basicBlock->getInstructions();
usedelete(iter->get()); SysYIROptUtils::usedelete(iter->get());
iter = instructions.erase(iter); iter = instructions.erase(iter);
if (basicBlock->getNumInstructions() == 0) { if (basicBlock->getNumInstructions() == 0) {
if (basicBlock->getNumSuccessors() == 1) { if (basicBlock->getNumSuccessors() == 1) {
@ -119,11 +119,4 @@ void Reg2Mem::DeletePhiInst(){
} }
} }
void Reg2Mem::usedelete(Instruction *instr) {
for (auto &use : instr->getOperands()) {
auto val = use->getValue();
val->removeUse(use);
}
}
} // namespace sysy } // namespace sysy

View File

@ -1,4 +1,5 @@
#include "SysYIROptPre.h" #include "SysYIROptPre.h"
#include "SysYIROptUtils.h"
#include <cassert> #include <cassert>
#include <list> #include <list>
#include <map> #include <map>
@ -10,18 +11,6 @@
namespace sysy { namespace sysy {
/**
* use删除operand,以免扰乱后续分析
* instr: 要删除的指令
*/
void SysYOptPre::usedelete(Instruction *instr) {
for (auto &use : instr->getOperands()) {
Value* val = use->getValue();
// std::cout << delete << val->getName() << std::endl;
val->removeUse(use);
}
}
// 删除br后的无用指令 // 删除br后的无用指令
void SysYOptPre::SysYDelInstAfterBr() { void SysYOptPre::SysYDelInstAfterBr() {
@ -34,7 +23,7 @@ void SysYOptPre::SysYDelInstAfterBr() {
auto Branchiter = instructions.end(); auto Branchiter = instructions.end();
for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) { for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) {
if (Branch) if (Branch)
usedelete(iter->get()); SysYIROptUtils::usedelete(iter->get());
else if ((*iter)->isTerminator()){ else if ((*iter)->isTerminator()){
Branch = true; Branch = true;
Branchiter = iter; Branchiter = iter;
@ -69,7 +58,7 @@ void SysYOptPre::SysYDelInstAfterBr() {
} }
} }
// 合并空基本块
void SysYOptPre::SysYBlockMerge() { void SysYOptPre::SysYBlockMerge() {
auto &functions = pModule->getFunctions(); //std::map<std::string, std::unique_ptr<Function>> auto &functions = pModule->getFunctions(); //std::map<std::string, std::unique_ptr<Function>>
for (auto &function : functions) { for (auto &function : functions) {
@ -91,12 +80,12 @@ void SysYOptPre::SysYBlockMerge() {
auto thelastinstinst = block->end(); auto thelastinstinst = block->end();
(--thelastinstinst); (--thelastinstinst);
if (thelastinstinst->get()->isUnconditional()) { if (thelastinstinst->get()->isUnconditional()) {
usedelete(thelastinstinst->get()); SysYIROptUtils::usedelete(thelastinstinst->get());
block->getInstructions().erase(thelastinstinst); block->getInstructions().erase(thelastinstinst);
} else if (thelastinstinst->get()->isConditional()) { } else if (thelastinstinst->get()->isConditional()) {
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式 // 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) { if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) {
usedelete(thelastinstinst->get()); SysYIROptUtils::usedelete(thelastinstinst->get());
block->getInstructions().erase(thelastinstinst); block->getInstructions().erase(thelastinstinst);
} }
} }
@ -170,7 +159,7 @@ void SysYOptPre::SysYDelNoPreBLock() {
if (!blockIter->get()->getreachable()) if (!blockIter->get()->getreachable())
for (auto &iterInst : blockIter->get()->getInstructions()) for (auto &iterInst : blockIter->get()->getInstructions())
usedelete(iterInst.get()); SysYIROptUtils::usedelete(iterInst.get());
} }
@ -303,7 +292,7 @@ void SysYOptPre::SysYDelEmptyBlock() {
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) == if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) { dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)); auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
usedelete(thelastinst->get()); SysYIROptUtils::usedelete(thelastinst->get());
thelastinst = basicBlock->getInstructions().erase(thelastinst); thelastinst = basicBlock->getInstructions().erase(thelastinst);
pBuilder->setPosition(basicBlock.get(), basicBlock->end()); pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(thebrBlock, {}); pBuilder->createUncondBrInst(thebrBlock, {});
@ -344,7 +333,7 @@ void SysYOptPre::SysYDelEmptyBlock() {
if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) == if (dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)) ==
dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) { dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2))) {
auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1)); auto thebrBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
usedelete(thelastinst->get()); SysYIROptUtils::usedelete(thelastinst->get());
thelastinst = basicBlock->getInstructions().erase(thelastinst); thelastinst = basicBlock->getInstructions().erase(thelastinst);
pBuilder->setPosition(basicBlock.get(), basicBlock->end()); pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(thebrBlock, {}); pBuilder->createUncondBrInst(thebrBlock, {});
@ -420,7 +409,7 @@ void SysYOptPre::SysYDelEmptyBlock() {
} }
for (auto &iterInst : iter->get()->getInstructions()) for (auto &iterInst : iter->get()->getInstructions())
usedelete(iterInst.get()); SysYIROptUtils::usedelete(iterInst.get());
// 删除不可达基本块的phi指令的操作数 // 删除不可达基本块的phi指令的操作数
for (auto &succ : iter->get()->getSuccessors()) { for (auto &succ : iter->get()->getSuccessors()) {
int index = 0; int index = 0;

View File

@ -3,6 +3,7 @@
#include "IR.h" #include "IR.h"
#include "SysYIRAnalyser.h" #include "SysYIRAnalyser.h"
#include "SysYIRPrinter.h" #include "SysYIRPrinter.h"
#include "SysYIROptUtils.h"
namespace sysy { namespace sysy {
@ -31,9 +32,5 @@ class DeadCodeElimination {
void eliminateDeadGlobals(bool& changed); // 消除无用全局变量 void eliminateDeadGlobals(bool& changed); // 消除无用全局变量
void eliminateDeadIndirectiveAllocas(Function* func, bool& changed); // 消除无用间接内存分配(phi节点) void eliminateDeadIndirectiveAllocas(Function* func, bool& changed); // 消除无用间接内存分配(phi节点)
void eliminateDeadRedundantLoadStore(Function* func, bool& changed); // 消除冗余加载和存储 void eliminateDeadRedundantLoadStore(Function* func, bool& changed); // 消除冗余加载和存储
bool isGlobal(Value *val);
bool isArr(Value *val);
void usedelete(Instruction *instr);
}; };
} // namespace sysy } // namespace sysy

View File

@ -8,6 +8,7 @@
#include "IR.h" #include "IR.h"
#include "IRBuilder.h" #include "IRBuilder.h"
#include "SysYIRAnalyser.h" #include "SysYIRAnalyser.h"
#include "SysYIROptUtils.h"
namespace sysy { namespace sysy {
/** /**
@ -51,9 +52,6 @@ private:
auto getPredIndex(BasicBlock *n, BasicBlock *s) -> int; ///< 获取前驱索引 auto getPredIndex(BasicBlock *n, BasicBlock *s) -> int; ///< 获取前驱索引
auto cascade(Instruction *instr, bool &changed, Function *func, BasicBlock *block, auto cascade(Instruction *instr, bool &changed, Function *func, BasicBlock *block,
std::list<std::unique_ptr<Instruction>> &instrs) -> void; ///< 消除级联关系 std::list<std::unique_ptr<Instruction>> &instrs) -> void; ///< 消除级联关系
auto isGlobal(Value *val) -> bool; ///< 判断是否是全局变量
auto isArr(Value *val) -> bool; ///< 判断是否是数组
auto usedelete(Instruction *instr) -> void; ///< 删除指令相关的value-use-user关系
}; };
} // namespace sysy } // namespace sysy

View File

@ -2,6 +2,7 @@
#include "IR.h" #include "IR.h"
#include "IRBuilder.h" #include "IRBuilder.h"
#include "SysYIROptUtils.h"
namespace sysy { namespace sysy {
/** /**
@ -16,8 +17,6 @@ public:
Reg2Mem(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {} Reg2Mem(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
void DeletePhiInst(); void DeletePhiInst();
// 删除UD关系, 因为删除了phi指令会修改ud关系
void usedelete(Instruction *instr);
}; };
} // namespace sysy } // namespace sysy

View File

@ -10,6 +10,11 @@ namespace sysy {
// 这些操作可以在SysY IR生成时就完成但为了简化IR生成过程 // 这些操作可以在SysY IR生成时就完成但为了简化IR生成过程
// 这里将其放在SysY IR生成后进行预处理 // 这里将其放在SysY IR生成后进行预处理
// 同时兼容phi节点的处理可以再mem2reg后再次调用优化 // 同时兼容phi节点的处理可以再mem2reg后再次调用优化
//TODO: 可增加的CFG优化
// - 简化条件分支Branch Simplification如条件恒真/恒假转为直接跳转
// - 合并连续的跳转指令Jump Threading在合并不可达块中似乎已经实现了
// - 基本块重排序Block Reordering提升局部性
class SysYOptPre { class SysYOptPre {
private: private:
Module *pModule; Module *pModule;
@ -31,7 +36,6 @@ class SysYOptPre {
void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块 void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块
// 也可以修改IR生成实现回填机制 // 也可以修改IR生成实现回填机制
void SysYAddReturn(); // 添加return指令(主要针对Void函数) void SysYAddReturn(); // 添加return指令(主要针对Void函数)
void usedelete(Instruction *instr); // use删除
}; };
} // namespace sysy } // namespace sysy

View File

@ -0,0 +1,33 @@
#pragma once
#include "IR.h"
namespace sysy {
// 优化工具类,包含一些通用的优化方法
// 这些方法可以在不同的优化 pass 中复用
// 例如删除use关系,判断是否是全局变量等
class SysYIROptUtils{
public:
// 删除use关系
static void usedelete(Instruction *instr) {
for (auto &use : instr->getOperands()) {
Value* val = use->getValue();
val->removeUse(use);
}
}
// 判断是否是全局变量
static bool isGlobal(Value *val) {
auto gval = dynamic_cast<GlobalValue *>(val);
return gval != nullptr;
}
// 判断是否是数组
static bool isArr(Value *val) {
auto aval = dynamic_cast<AllocaInst *>(val);
return aval != nullptr && aval->getNumDims() != 0;
}
};
}// namespace sysy