IRoptpre 初步构建
This commit is contained in:
17
TODO.md
17
TODO.md
@ -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
173
src/SysYIROptPre.cpp
Normal 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
|
||||
27
src/include/SysYIROptPre.h
Normal file
27
src/include/SysYIROptPre.h
Normal 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
|
||||
Reference in New Issue
Block a user