IRoptpre 初步构建

This commit is contained in:
rain2133
2025-06-23 13:17:15 +08:00
parent 63fc92dcbd
commit 568e9af626
4 changed files with 214 additions and 7 deletions

17
TODO.md
View File

@ -3,20 +3,27 @@
### 1. **前端必须模块**
- **词法/语法分析**(已完成):
- `SysYLexer`/`SysYParser`ANTLR生成的解析器
- **IR生成核心**
- **IR生成核心**(已完成)
- `SysYIRGenerator`将AST转换为中间表示IR
- `IRBuilder`:构建指令和基本块的工具类(你们正在实现的部分)
- **IR打印器**(基本完成)
- `SysYIRPrinter`: 打印llvm ir格式的指令优化遍后查看优化效果la指令,subarray数组翻译范式需要改进
### 2. **中端必要优化(最小集合)**
- **CFG优化**(待测试)
- `SysYIROptPre`CFG优化顺便解决IR生成的缺陷void自动添加ret指令合并嵌套if/while语句生成的多个exit后续可以实现回填机制
常量传播
| 优化阶段 | 关键作用 | 是否必须 |
|-------------------|----------------------------------|----------|
| `Mem2Reg` | 消除冗余内存访问转换为SSA形式 | ✅ 核心 |
| `DCE` (死代码消除) | 移除无用指令 | ✅ 必要 |
| `DFE` (死函数消除) | 移除未使用的函数 | ✅ 必要 |
| `FuncAnalysis` | 函数调用关系分析 | ✅ 基础 |
| `Mem2Reg` | 消除冗余内存访问转换为SSA形式 | ✅ 核心 |(必须)
| `DCE` (死代码消除) | 移除无用指令 | ✅ 必要 |(必须)
| `DFE` (死函数消除) | 移除未使用的函数 | ✅ 必要 |(必须)
| `Global2Local` | 全局变量降级为局部变量 | ✅ 重要 |
还需要做 Reg2Mem
### 3. **后端核心流程(必须实现)**
```mermaid
graph LR

173
src/SysYIROptPre.cpp Normal file
View File

@ -0,0 +1,173 @@
/**
* @file: Sysyoptimization.cpp
* @brief CFG优化
* @Author : Ixeux email:you@domain.com
* @Version : 1.0
* @Creat Date : 2024-08-10
*
*/
#include "SysYIROptPre.h"
#include <cassert>
#include <list>
#include <map>
#include <memory>
#include <string>
#include "IR.h"
#include "IRBuilder.h"
namespace sysy {
void SysYOptPre::SysYOptimizateAll() -> void {
SysYDelAfterBr();
SysYBlockMerge();
SysYDelNoPreBLock();
SysYDelEmptyBlock();
SysYAddReturn();
}
/**
* 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后的无用指令
void SysYOptPre::SysYDelInstAfterBr() {
auto &functions = pModule->getFunctions();
for (auto &function : functions) {
auto basicBlocks = function.second->getBasicBlocks();
for (auto &basicBlock : basicBlocks) {
bool Branch = false;
auto &instructions = basicBlock->getInstructions();
auto iter = instructions.begin();
auto Branchiter = instructions.end();
for (auto iter = instructions->begin(); iter != instructions->end();iter++) {
if (Branch)
usedelete(iter->get());
else if ((*iter)->isTerminator()){
Branch = true;
Branchiter = iter;
}
}
Branchiter++;
while(Branchiter != instructions->begin())
Branchiter = instructions.erase(Branchiter);
if (Branch) { // 更新前驱后继关系
auto thelastinst = basicBlock->getInstructions().end();
--thelastinst;
auto &Successors = basicBlock->getSuccessors();
for (auto iterSucc = Successors.begin(); iterSucc != Successors.end();) {
(*iterSucc)->removePredecessor(basicBlock.get());
basicBlock->removeSuccessor(*iterSucc);
}
if (thelastinst->get()->isUnconditional()) {
BasicBlock* branchBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(0));
basicBlock->addSuccessor(branchBlock);
branchBlock->addPredecessor(basicBlock.get());
} else if (thelastinst->get()->isConditional()) {
BasicBlock* thenBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(1));
BasicBlock* elseBlock = dynamic_cast<BasicBlock *>(thelastinst->get()->getOperand(2));
basicBlock->addSuccessor(thenBlock);
basicBlock->addSuccessor(elseBlock);
thenBlock->addPredecessor(basicBlock.get());
elseBlock->addPredecessor(basicBlock.get());
}
}
}
}
}
void SysYOptPre::SysYBlockMerge() {
auto &functions = pModule->getFunctions(); //std::map<std::string, std::unique_ptr<Function>>
for (auto &function : functions) {
// auto basicBlocks = function.second->getBasicBlocks();
Function* func = function.second.get();
for (auto blockiter = func->getBasicBlocks().begin();
blockiter != func->getBasicBlocks().end();) {
if (blockiter->get()->getNumSuccessors() == 1) {
// 如果当前块只有一个后继块
// 且后继块只有一个前驱块
// 则将当前块和后继块合并
if (((blockiter->get())->getSuccessors()[0])->getNumPredecessors() == 1) {
// std::cout << "merge block: " << blockiter->get()->getName() << std::endl;
BasicBlock* block = blockiter->get();
BasicBlock* nextBlock = blockiter->get()->getSuccessors()[0];
auto nextarguments = nextBlock->getArguments();
// 删除br指令
if (block->getNumInstructions() != 0) {
auto thelastinst = block->end();
(--thelastinst);
if (thelastinst->get()->isUnconditional()) {
usedelete(thelastinst->get());
block->getInstructions().erase(thelastinst);
} else if (thelastinst->get()->isConditional()) {
// 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式
if (thelastinst->get()->getOperand(1)->getName() == thelastinst->get()->getOperand(1)->getName()) {
usedelete(thelastinst->get());
block->getInstructions().erase(thelastinst);
}
}
}
// 将后继块的指令移动到当前块
// 并将后继块的父指针改为当前块
for (auto institer = nextBlock->begin(); institer != nextBlock->end();) {
institer->get()->setParent(block);
block->getInstructions().emplace_back(institer->release());
institer = nextBlock->getInstructions().erase(institer);
}
// 合并参数
for (auto &argm : nextarguments) {
argm->setParent(block);
block->insertArgument(argm);
}
// // // 改变block 和 next 之间的关系
block->removeSuccessor(nextBlock);
nextBlock->removePredecessor(block);
std::list<BasicBlock *> succshoulddel;
for (auto &succ : nextBlock->getSuccessors()) {
block->addSuccessor(succ);
succ->replacePredecessor(nextBlock, block);
succshoulddel.push_back(succ);
}
for (auto del : succshoulddel) {
nextBlock->removeSuccessor(del);
}
// // // 添加block 和 next 的后继 之间的关系
// block->addSuccessor(nextBlock->getSuccessors()[0]);
// nextBlock->getSuccessors()[0]->addPredecessor(blockiter->get());
// // // 删除next 和 next后继的关系
// nextBlock->getSuccessors()[0]->removePredecessor(nextBlock);
// nextBlock->removeSuccessor(nextBlock->getSuccessors()[0]);
// std::cout << nextBlock->getName() << std::endl;
function.second->removeBasicBlock(nextBlock);
// ++blockiter;
} else {
blockiter++;
}
} else {
blockiter++;
}
}
}
}
void SysYOptPre::SysYDelNoPreBLock() {
}
void SysYOptPre::SysYAddReturn() {
}
} // namespace sysy

View File

@ -372,9 +372,9 @@ class BasicBlock;
unsigned getNumPredecessors() const { return predecessors.size(); } ///< 获取前驱数量
unsigned getNumSuccessors() const { return successors.size(); } ///< 获取后继数量
Function* getParent() const { return parent; } ///< 获取父函数
void setParent(Function *func) { parent = func; } ///< 设置父函数
void setParent(Function *func) { parent = func; } ///< 设置父函数
inst_list& getInstructions() { return instructions; } ///< 获取指令列表
arg_list& getArguments() { return arguments; } ///< 获取分配空间后的形式参数列表
arg_list& getArguments() { return arguments; } ///< 获取分配空间后的形式参数列表
const block_list& getPredecessors() const { return predecessors; } ///< 获取前驱列表
block_list& getSuccessors() { return successors; } ///< 获取后继列表
block_set& getDominants() { return dominants; }

View File

@ -0,0 +1,27 @@
#pragma once
#include "IR.h"
#include "IRBuilder.h"
namespace sysy {
// 优化前对SysY IR的预处理也可以视作部分CFG优化
// 主要包括删除无用指令、合并基本块、删除空块等
class SysYOptPre {
private:
Module *pModule;
IRBuilder *pBuilder;
public:
SysYOptPre(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {}
void SysYDelInstAfterBr(); // 删除br后面的指令
void SysYDelEmptyBlock(); // 空块删除
void SysYDelNoPreBLock(); // 删除无前驱块
void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块
// 也可以修改IR生成实现回填机制
void SysYAddReturn(); // 添加return指令(主要针对Void函数)
void usedelete(); // use删除
};
} // namespace sysy