diff --git a/TODO.md b/TODO.md index aae2f4e..80b4745 100644 --- a/TODO.md +++ b/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 diff --git a/src/SysYIROptPre.cpp b/src/SysYIROptPre.cpp new file mode 100644 index 0000000..3123801 --- /dev/null +++ b/src/SysYIROptPre.cpp @@ -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 +#include +#include +#include +#include +#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(thelastinst->get()->getOperand(0)); + basicBlock->addSuccessor(branchBlock); + branchBlock->addPredecessor(basicBlock.get()); + } else if (thelastinst->get()->isConditional()) { + BasicBlock* thenBlock = dynamic_cast(thelastinst->get()->getOperand(1)); + BasicBlock* elseBlock = dynamic_cast(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> + 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 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 diff --git a/src/include/IR.h b/src/include/IR.h index b8cd1ba..25f44ed 100644 --- a/src/include/IR.h +++ b/src/include/IR.h @@ -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; } diff --git a/src/include/SysYIROptPre.h b/src/include/SysYIROptPre.h new file mode 100644 index 0000000..71a723d --- /dev/null +++ b/src/include/SysYIROptPre.h @@ -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