增加Reg2Mem,但是会生成死存储指令,需要死代码删除支持识别死存储指令

This commit is contained in:
rain2133
2025-06-25 13:17:16 +08:00
parent 3dc7c274cf
commit 050113d31d
5 changed files with 161 additions and 13 deletions

View File

@@ -20,6 +20,7 @@ add_executable(sysyc
SysYIROptPre.cpp
SysYIRAnalyser.cpp
Mem2Reg.cpp
Reg2Mem.cpp
RISCv32Backend.cpp
)
target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)

View File

@@ -570,7 +570,7 @@ auto Mem2Reg::preOptimize3() -> void {
}
/**
* @brief 为所有变量的定义块集合的迭代支配边界插入phi结点(剪枝版)
* @brief 为所有变量的定义块集合的迭代支配边界插入phi结点
*
* insertPhi是mem2reg的核心之一这里是对所有变量的迭代支配边界的phi结点插入无参数也无返回值
* 同样跳过对数组和全局变量的处理因为这些变量不会被mem2reg优化刚好这里在计算value2DefBlocks时已经跳过了所以不需要再显式处理了
@@ -796,10 +796,7 @@ auto Mem2Reg::getPredIndex(BasicBlock *n, BasicBlock *s) -> int {
}
/**
* @brief 判断一个value是不是全局变量
*
* @param [in] val 一个value
* @return 返回true表示是全局变量返回false表示不是
* 判断一个value是不是全局变量
*/
auto Mem2Reg::isGlobal(Value *val) -> bool {
auto gval = dynamic_cast<GlobalValue *>(val);
@@ -807,10 +804,7 @@ auto Mem2Reg::isGlobal(Value *val) -> bool {
}
/**
* @brief 判断一个value是不是数组
*
* @param [in] val 一个value
* @return 返回true表示是数组返回false表示不是
* 判断一个value是不是数组
*/
auto Mem2Reg::isArr(Value *val) -> bool {
auto aval = dynamic_cast<AllocaInst *>(val);
@@ -818,10 +812,7 @@ auto Mem2Reg::isArr(Value *val) -> bool {
}
/**
* @brief 删除一个指令的operand对应的value的该条use
*
* @param [in] inst 一条指令
* @return 无返回值
* 删除一个指令的operand对应的value的该条use
*/
auto Mem2Reg::usedelete(Instruction *instr) -> void {
for (auto &use : instr->getOperands()) {

View File

@@ -0,0 +1,129 @@
#include "Reg2Mem.h"
#include <cstddef>
#include <iostream>
#include <list>
#include <memory>
namespace sysy {
/**
* 删除phi节点
* 删除phi节点后可能会生成冗余存储代码
*/
void Reg2Mem::DeletePhiInst(){
auto &functions = pModule->getFunctions();
for (auto &function : functions) {
auto basicBlocks = function.second->getBasicBlocks();
for (auto &basicBlock : basicBlocks) {
for (auto iter = basicBlock->begin(); iter != basicBlock->end();) {
auto &instruction = *iter;
if (instruction->isPhi()) {
auto predBlocks = basicBlock->getPredecessors();
// 寻找源和目的
// 目的就是phi指令的第一个操作数
// 源就是phi指令的后续操作数
auto destination = instruction->getOperand(0);
int predBlockindex = 0;
for (auto &predBlock : predBlocks) {
++predBlockindex;
// 判断前驱块儿只有一个后继还是多个后继
// 如果有多个
auto source = instruction->getOperand(predBlockindex);
if (source == destination) {
continue;
}
// std::cout << predBlock->getNumSuccessors() << std::endl;
if (predBlock->getNumSuccessors() > 1) {
// 创建一个basicblock
auto newbasicBlock = function.second->addBasicBlock();
std::stringstream ss;
ss << " phidel.L" << pBuilder->getLabelIndex();
newbasicBlock->setName(ss.str());
ss.str("");
// // 修改前驱后继关系
basicBlock->replacePredecessor(predBlock, newbasicBlock);
// predBlock = newbasicBlock;
newbasicBlock->addPredecessor(predBlock);
newbasicBlock->addSuccessor(basicBlock.get());
predBlock->removeSuccessor(basicBlock.get());
predBlock->addSuccessor(newbasicBlock);
// std::cout << "the block name is " << basicBlock->getName() << std::endl;
// for (auto pb : basicBlock->getPredecessors()) {
// // newbasicBlock->addPredecessor(pb);
// std::cout << pb->getName() << std::endl;
// }
// sysy::BasicBlock::conectBlocks(newbasicBlock, static_cast<BasicBlock *>(basicBlock.get()));
// 若后为跳转指令,应该修改跳转指令所到达的位置
auto thelastinst = predBlock->end();
(--thelastinst);
if (thelastinst->get()->isConditional() || thelastinst->get()->isUnconditional()) { // 如果是跳转指令
auto opnum = thelastinst->get()->getNumOperands();
for (size_t i = 0; i < opnum; i++) {
if (thelastinst->get()->getOperand(i) == basicBlock.get()) {
thelastinst->get()->replaceOperand(i, newbasicBlock);
}
}
}
// 在新块中插入store指令
pBuilder->setPosition(newbasicBlock, newbasicBlock->end());
// pBuilder->createStoreInst(source, destination);
if (source->isInt() || source->isFloat()) {
pBuilder->createStoreInst(source, destination);
} else {
auto loadInst = pBuilder->createLoadInst(source);
pBuilder->createStoreInst(loadInst, destination);
}
// pBuilder->createMoveInst(Instruction::kMove, destination->getType(), destination, source,
// newbasicBlock);
pBuilder->setPosition(newbasicBlock, newbasicBlock->end());
pBuilder->createUncondBrInst(basicBlock.get(), {});
} else {
// 如果前驱块只有一个后继
auto thelastinst = predBlock->end();
(--thelastinst);
// std::cout << predBlock->getName() << std::endl;
// std::cout << thelastinst->get() << std::endl;
// std::cout << "First point 11 " << std::endl;
if (thelastinst->get()->isConditional() || thelastinst->get()->isUnconditional()) {
// 在跳转语句前insert st指令
pBuilder->setPosition(predBlock, thelastinst);
} else {
pBuilder->setPosition(predBlock, predBlock->end());
}
if (source->isInt() || source->isFloat()) {
pBuilder->createStoreInst(source, destination);
} else {
auto loadInst = pBuilder->createLoadInst(source);
pBuilder->createStoreInst(loadInst, destination);
}
}
}
// 删除phi指令
auto &instructions = basicBlock->getInstructions();
usedelete(iter->get());
iter = instructions.erase(iter);
if (basicBlock->getNumInstructions() == 0) {
if (basicBlock->getNumSuccessors() == 1) {
pBuilder->setPosition(basicBlock.get(), basicBlock->end());
pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {});
}
}
} else {
break;
}
}
}
}
}
void Reg2Mem::usedelete(Instruction *instr) {
for (auto &use : instr->getOperands()) {
auto val = use->getValue();
val->removeUse(use);
}
}
} // namespace sysy

View File

@@ -0,0 +1,23 @@
#pragma once
#include "IR.h"
#include "IRBuilder.h"
namespace sysy {
/**
* Reg2Mem(后端未做phi指令翻译)
*/
class Reg2Mem {
private:
Module *pModule;
IRBuilder *pBuilder;
public:
Reg2Mem(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
void DeletePhiInst();
// 删除UD关系, 因为删除了phi指令会修改ud关系
void usedelete(Instruction *instr);
};
} // namespace sysy

View File

@@ -12,6 +12,7 @@ using namespace antlr4;
#include "SysYIROptPre.h"
#include "SysYIRAnalyser.h"
#include "Mem2Reg.h"
#include "Reg2Mem.h"
// #include "LLVMIRGenerator.h"
using namespace sysy;
@@ -88,6 +89,9 @@ int main(int argc, char **argv) {
Mem2Reg mem2reg(moduleIR, builder);
mem2reg.mem2regPipeline();
printer.printIR();
Reg2Mem reg2mem(moduleIR, builder);
reg2mem.DeletePhiInst();
printer.printIR();
return EXIT_SUCCESS;
}
return EXIT_SUCCESS;