From 9d8930f5df5ee2044b6c85fe0af48026152f38fe Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Mon, 23 Jun 2025 00:22:15 +0800 Subject: [PATCH 1/5] fix % repeat in IR print --- src/Mem2Reg.cpp | 0 src/SysYIRGenerator.cpp | 12 +++++++----- src/SysYIRPrinter.cpp | 4 +--- src/include/IRBuilder.h | 10 +++++----- src/include/Mem2Reg.h | 0 5 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 src/Mem2Reg.cpp create mode 100644 src/include/Mem2Reg.h diff --git a/src/Mem2Reg.cpp b/src/Mem2Reg.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 1718aba..912930e 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -73,10 +73,12 @@ std::any SysYIRGenerator::visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *c } } - ArrayValueTree* root = std::any_cast(varDef->initVal()->accept(this)); - ValueCounter values; - Utils::tree2Array(type, root, dims, dims.size(), values, &builder); - delete root; + ValueCounter values = {}; + if (varDef->initVal() != nullptr) { + ArrayValueTree* root = std::any_cast(varDef->initVal()->accept(this)); + Utils::tree2Array(type, root, dims, dims.size(), values, &builder); + delete root; + } // 创建全局变量,并更新符号表 module->createGlobalValue(name, Type::getPointerType(type), dims, values); } @@ -456,7 +458,7 @@ std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext *ctx) { returnValue = std::any_cast(visitExp(ctx->exp())); } - Type* funcType = builder.getBasicBlock()->getParent()->getType(); + Type* funcType = builder.getBasicBlock()->getParent()->getReturnType(); if (funcType!= returnValue->getType() && returnValue != nullptr) { ConstantValue * constValue = dynamic_cast(returnValue); if (constValue != nullptr) { diff --git a/src/SysYIRPrinter.cpp b/src/SysYIRPrinter.cpp index 5be7777..4812106 100644 --- a/src/SysYIRPrinter.cpp +++ b/src/SysYIRPrinter.cpp @@ -11,9 +11,7 @@ void SysYPrinter::printIR() { const auto &functions = pModule->getFunctions(); - // Print target datalayout and triple (minimal required by LLVM) - std::cout << "target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128\"\n"; - std::cout << "target triple = \"i386-pc-linux-gnu\"\n\n"; + //TODO: Print target datalayout and triple (minimal required by LLVM) printGlobalVariable(); diff --git a/src/include/IRBuilder.h b/src/include/IRBuilder.h index 9189cba..8798a2e 100644 --- a/src/include/IRBuilder.h +++ b/src/include/IRBuilder.h @@ -96,7 +96,7 @@ class IRBuilder { std::string newName; if (name.empty()) { std::stringstream ss; - ss << "%" << tmpIndex; + ss << tmpIndex; newName = ss.str(); tmpIndex++; } else { @@ -136,7 +136,7 @@ class IRBuilder { std::string newName; if (name.empty()) { std::stringstream ss; - ss << "%" << tmpIndex; + ss << tmpIndex; newName = ss.str(); tmpIndex++; } else { @@ -221,7 +221,7 @@ class IRBuilder { std::string newName; if (name.empty() && callee->getReturnType() != Type::getVoidType()) { std::stringstream ss; - ss << "%" << tmpIndex; + ss << tmpIndex; newName = ss.str(); tmpIndex++; } else { @@ -268,7 +268,7 @@ class IRBuilder { std::string newName; if (name.empty()) { std::stringstream ss; - ss << "%" << tmpIndex; + ss << tmpIndex; newName = ss.str(); tmpIndex++; } else { @@ -284,7 +284,7 @@ class IRBuilder { std::string newName; if (name.empty()) { std::stringstream ss; - ss << "%" << tmpIndex; + ss << tmpIndex; newName = ss.str(); tmpIndex++; } else { diff --git a/src/include/Mem2Reg.h b/src/include/Mem2Reg.h new file mode 100644 index 0000000..e69de29 From 63fc92dcbd089245251f8c0b4152570246c475e5 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Mon, 23 Jun 2025 11:35:44 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=95=B0=E7=BB=84=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/IRBuilder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/IRBuilder.h b/src/include/IRBuilder.h index 8798a2e..088427f 100644 --- a/src/include/IRBuilder.h +++ b/src/include/IRBuilder.h @@ -315,7 +315,7 @@ class IRBuilder { auto fatherArrayValue = dynamic_cast(fatherArray); auto childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block, childArrayName); - auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block, name); + auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block, childArrayName); assert(inst); block->getInstructions().emplace(position, inst); return inst; From 568e9af6262ff3ec121ce8b1bde969af9f028a05 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Mon, 23 Jun 2025 13:17:15 +0800 Subject: [PATCH 3/5] =?UTF-8?q?IRoptpre=20=E5=88=9D=E6=AD=A5=E6=9E=84?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 17 ++-- src/SysYIROptPre.cpp | 173 +++++++++++++++++++++++++++++++++++++ src/include/IR.h | 4 +- src/include/SysYIROptPre.h | 27 ++++++ 4 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 src/SysYIROptPre.cpp create mode 100644 src/include/SysYIROptPre.h 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 From 3d233ff19901f1932366b4082bccf887e6f9307b Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Mon, 23 Jun 2025 16:25:52 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90CFG?= =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=88IR=E4=BF=AE=E5=A4=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SysYIROptPre.cpp | 389 +++++++++++++++++++++++++++++++++---- src/include/SysYIROptPre.h | 10 + 2 files changed, 363 insertions(+), 36 deletions(-) diff --git a/src/SysYIROptPre.cpp b/src/SysYIROptPre.cpp index 3123801..edd9333 100644 --- a/src/SysYIROptPre.cpp +++ b/src/SysYIROptPre.cpp @@ -17,14 +17,6 @@ namespace sysy { -void SysYOptPre::SysYOptimizateAll() -> void { - SysYDelAfterBr(); - SysYBlockMerge(); - SysYDelNoPreBLock(); - SysYDelEmptyBlock(); - SysYAddReturn(); -} - /** * use删除operand,以免扰乱后续分析 * instr: 要删除的指令 @@ -61,20 +53,20 @@ void SysYOptPre::SysYDelInstAfterBr() { Branchiter = instructions.erase(Branchiter); if (Branch) { // 更新前驱后继关系 - auto thelastinst = basicBlock->getInstructions().end(); - --thelastinst; + auto thelastinstinst = basicBlock->getInstructions().end(); + --thelastinstinst; 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)); + if (thelastinstinst->get()->isUnconditional()) { + BasicBlock* branchBlock = dynamic_cast(thelastinstinst->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)); + } else if (thelastinstinst->get()->isConditional()) { + BasicBlock* thenBlock = dynamic_cast(thelastinstinst->get()->getOperand(1)); + BasicBlock* elseBlock = dynamic_cast(thelastinstinst->get()->getOperand(2)); basicBlock->addSuccessor(thenBlock); basicBlock->addSuccessor(elseBlock); thenBlock->addPredecessor(basicBlock.get()); @@ -90,7 +82,7 @@ void SysYOptPre::SysYBlockMerge() { auto &functions = pModule->getFunctions(); //std::map> for (auto &function : functions) { // auto basicBlocks = function.second->getBasicBlocks(); - Function* func = function.second.get(); + auto &func = function.second; for (auto blockiter = func->getBasicBlocks().begin(); blockiter != func->getBasicBlocks().end();) { if (blockiter->get()->getNumSuccessors() == 1) { @@ -104,16 +96,16 @@ void SysYOptPre::SysYBlockMerge() { 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()) { + auto thelastinstinst = block->end(); + (--thelastinstinst); + if (thelastinstinst->get()->isUnconditional()) { + usedelete(thelastinstinst->get()); + block->getInstructions().erase(thelastinstinst); + } else if (thelastinstinst->get()->isConditional()) { // 如果是条件分支,判断条件是否相同,主要优化相同布尔表达式 - if (thelastinst->get()->getOperand(1)->getName() == thelastinst->get()->getOperand(1)->getName()) { - usedelete(thelastinst->get()); - block->getInstructions().erase(thelastinst); + if (thelastinstinst->get()->getOperand(1)->getName() == thelastinstinst->get()->getOperand(1)->getName()) { + usedelete(thelastinstinst->get()); + block->getInstructions().erase(thelastinstinst); } } } @@ -125,11 +117,12 @@ void SysYOptPre::SysYBlockMerge() { institer = nextBlock->getInstructions().erase(institer); } // 合并参数 + // TODO:是否需要去重? for (auto &argm : nextarguments) { argm->setParent(block); block->insertArgument(argm); } - // // // 改变block 和 next 之间的关系 + // 更新前驱后继关系,类似树节点操作 block->removeSuccessor(nextBlock); nextBlock->removePredecessor(block); std::list succshoulddel; @@ -142,16 +135,8 @@ void SysYOptPre::SysYBlockMerge() { 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; + func->removeBasicBlock(nextBlock); - function.second->removeBasicBlock(nextBlock); - // ++blockiter; } else { blockiter++; } @@ -162,12 +147,344 @@ void SysYOptPre::SysYBlockMerge() { } } - +// 删除无前驱块,兼容SSA后的处理 void SysYOptPre::SysYDelNoPreBLock() { + + auto &functions = pModule->getFunctions(); // std::map> + for (auto &function : functions) { + auto &func = function.second; + + for (auto &block : func->getBasicBlocks()) { + block->setreachableFalse(); + } + // 对函数基本块做一个拓扑排序,排查不可达基本块 + auto entryBlock = func->getEntryBlock(); + entryBlock->setreachableTrue(); + std::queue blockqueue; + blockqueue.push(entryBlock); + while (!blockqueue.empty()) { + auto block = blockqueue.front(); + blockqueue.pop(); + for (auto &succ : block->getSuccessors()) { + if (!succ->getreachable()) { + succ->setreachableTrue(); + blockqueue.push(succ); + } + } + } + + // 删除不可达基本块指令 + for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) { + + if (!blockIter->get()->getreachable()) + for (auto &iterInst : blockIter->get()->getInstructions()) + usedelete(iterInst.get()); + + } + + + for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) { + if (!blockIter->get()->getreachable()) { + //// 处理phi指令 + // 删除不可达基本块的phi指令的操作数 + for (auto succblock : blockIter->get()->getSuccessors()) { + int indexphi = 1; + for (auto pred : succblock->getPredecessors()) { + if (pred == blockIter->get()) { + break; + } + indexphi++; + } + for (auto &phiinst : succblock->getInstructions()) { + if (phiinst->getKind() != Instruction::kPhi) { + break; + } + phiinst->removeOperand(indexphi); + } + } + // 删除不可达基本块 + func->removeBasicBlock(blockIter->get()); + } + } + } } +void SysyOptimization::SysyDelEmptyBlock() { + auto &functions = pModule->getFunctions(); + for (auto &function : functions) { + // 收集不可达基本块 + // 这里的不可达基本块是指没有实际指令的基本块 + // 当一个基本块没有实际指令例如只有phi指令和一个uncondbr指令时,也会被视作不可达 + auto basicBlocks = function.second->getBasicBlocks(); + std::map EmptyBlocks; + // 空块儿和后继的基本块的映射 + for (auto &basicBlock : basicBlocks) { + if (basicBlock->getNumInstructions() == 0) { + if (basicBlock->getNumSuccessors() == 1) { + EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); + } + } + else{ + // 如果只有phi指令和一个uncondbr。(phi)*(uncondbr)? + // 判断除了最后一个指令之外是不是只有phi指令 + bool onlyPhi = true; + for (auto &inst : basicBlock->getInstructions()) { + if (!inst->isPhi() && !inst->isUnconditional()) { + onlyPhi = false; + break; + } + } + if(onlyPhi) + EmptyBlocks[basicBlock.get()] = basicBlock->getSuccessors().front(); + } + + + } + // 更新基本块信息,增加必要指令 + for (auto &basicBlock : basicBlocks) { + // 把空块转换成只有跳转指令的不可达块 + if (distance(basicBlock->begin(), basicBlock->end()) == 0) { + if (basicBlock->getNumSuccessors() == 0) { + continue; + } + if (basicBlock->getNumSuccessors() > 1) { + assert(""); + } + pBuilder->setPosition(basicBlock.get(), basicBlock->end()); + pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); + continue; + } + auto thelastinst = basicBlock->getInstructions().end(); + --thelastinst; + + // 根据br指令传递的后继块信息,跳过空块链 + if (thelastinst->get()->getKind()->isUnconditional()) { + BasicBlock* OldBrBlock = dynamic_cast(thelastinst->get()->getOperand(0)); + BasicBlock *thelastBlockOld = nullptr; + // 如果空块链表为多个块 + while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(0))) != + EmptyBlocks.end()) { + thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(0)); + thelastinst->get()->replaceOperand(0, EmptyBlocks[thelastBlockOld]); + } + + basicBlock->removeSuccessor(OldBrBlock); + OldBrBlock->removePredecessor(basicBlock.get()); + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); + dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); + + if (thelastBlockOld != nullptr) { + int indexphi = 0; + for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { + if (pred == thelastBlockOld) { + break; + } + indexphi++; + } + + // 更新phi指令的操作数 + // 移除thelastBlockOld对应的phi操作数 + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { + if (InstInNew->isPhi()) { + dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + } else { + break; + } + } + } + + } else if (thelastinst->get()->getKind() == Instruction::kCondBr) { + auto OldThenBlock = dynamic_cast(thelastinst->get()->getOperand(1)); + auto OldElseBlock = dynamic_cast(thelastinst->get()->getOperand(2)); + + BasicBlock *thelastBlockOld = nullptr; + while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(1))) != + EmptyBlocks.end()) { + thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(1)); + thelastinst->get()->replaceOperand( + 1, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(1))]); + } + basicBlock->removeSuccessor(OldThenBlock); + OldThenBlock->removePredecessor(basicBlock.get()); + // 处理 then 和 else 分支合并的情况 + if (dynamic_cast(thelastinst->get()->getOperand(1)) == + dynamic_cast(thelastinst->get()->getOperand(2))) { + auto thebrBlock = dynamic_cast(thelastinst->get()->getOperand(1)); + usedelete(thelastinst->get()); + thelastinst = basicBlock->getInstructions().erase(thelastinst); + pBuilder->setPosition(basicBlock.get(), basicBlock->end()); + pBuilder->createUncondBrInst(thebrBlock, {}); + continue; + } + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(1))); + dynamic_cast(thelastinst->get()->getOperand(1))->addPredecessor(basicBlock.get()); + // auto indexInNew = dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors(). + + if (thelastBlockOld != nullptr) { + int index = 0; + for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(1))->getPredecessors()) { + if (pred == thelastBlockOld) { + break; + } + index++; + } + + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { + if (InstInNew->isPhi()) { + dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + } else { + break; + } + } + } + + thelastBlockOld = nullptr; + while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(2))) != + EmptyBlocks.end()) { + thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(2)); + thelastinst->get()->replaceOperand( + 2, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(2))]); + } + basicBlock->removeSuccessor(OldElseBlock); + OldElseBlock->removePredecessor(basicBlock.get()); + // 处理 then 和 else 分支合并的情况 + if (dynamic_cast(thelastinst->get()->getOperand(1)) == + dynamic_cast(thelastinst->get()->getOperand(2))) { + auto thebrBlock = dynamic_cast(thelastinst->get()->getOperand(1)); + usedelete(thelastinst->get()); + thelastinst = basicBlock->getInstructions().erase(thelastinst); + pBuilder->setPosition(basicBlock.get(), basicBlock->end()); + pBuilder->createUncondBrInst(thebrBlock, {}); + continue; + } + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(2))); + dynamic_cast(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get()); + + if (thelastBlockOld != nullptr) { + int index = 0; + for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(2))->getPredecessors()) { + if (pred == thelastBlockOld) { + break; + } + index++; + } + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(2))->getInstructions()) { + if (InstInNew->isPhi()) { + dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + } else { + break; + } + } + } + } else { + if (basicBlock->getNumSuccessors() == 1) { + pBuilder->setPosition(basicBlock.get(), basicBlock->end()); + pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); + auto thelastinst = basicBlock->getInstructions().end(); + (--thelastinst); + auto OldBrBlock = dynamic_cast(thelastinst->get()->getOperand(0)); + sysy::BasicBlock *thelastBlockOld = nullptr; + while (EmptyBlocks.find(dynamic_cast(thelastinst->get()->getOperand(0))) != + EmptyBlocks.end()) { + thelastBlockOld = dynamic_cast(thelastinst->get()->getOperand(0)); + + thelastinst->get()->replaceOperand( + 0, EmptyBlocks[dynamic_cast(thelastinst->get()->getOperand(0))]); + } + + basicBlock->removeSuccessor(OldBrBlock); + OldBrBlock->removePredecessor(basicBlock.get()); + basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); + dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); + if (thelastBlockOld != nullptr) { + int index = 0; + for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { + if (pred == thelastBlockOld) { + break; + } + index++; + } + + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { + if (InstInNew->isPhi()) { + dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); + } else { + break; + } + } + } + } + } + } + + for (auto iter = function.second->getBasicBlocks().begin(); iter != function.second->getBasicBlocks().end();) { + + if (EmptyBlocks.find(iter->get()) != EmptyBlocks.end()) { + // EntryBlock跳过 + if (iter->get() == function.second->getEntryBlock()) { + ++iter; + continue; + } + + for (auto &iterInst : iter->get()->getInstructions()) + usedelete(iterInst.get()); + // 删除不可达基本块的phi指令的操作数 + for (auto &succ : iter->get()->getSuccessors()) { + int index = 0; + for (auto &pred : succ->getPredecessors()) { + if (pred == iter->get()) { + break; + } + index++; + } + + for (auto &instinsucc : succ->getInstructions()) { + if (instinsucc->isPhi()) { + dynamic_cast(instinsucc.get())->removeOperand(index); + } else { + break; + } + } + } + + function.second->removeBasicBlock((iter++)->get()); + } else { + ++iter; + } + } + } +} + +// 如果函数没有返回指令,则添加一个默认返回指令(主要解决void函数没有返回指令的问题) void SysYOptPre::SysYAddReturn() { + auto &functions = pModule->getFunctions(); + for (auto &function : functions) { + auto &func = function.second; + auto &basicBlocks = func->getBasicBlocks(); + for (auto &block : basicBlocks) { + if (block->getNumSuccessors() == 0) { + // 如果基本块没有后继块,则添加一个返回指令 + if (block->getNumInstructions() == 0) { + pBuilder->setPosition(block.get(), block->end()); + pBuilder->createReturnInst({}); + } + auto thelastinst = block->getInstructions().end(); + --thelastinst; + if (thelastinst->get()->getKind() != Instruction::kReturn) { + pBuilder->setPosition(block.get(), block->end()); + // TODO: 如果int float函数缺少返回值是否需要报错 + if (func->getReturnType()->isInt()) { + pBuilder->createReturnInst(ConstantValue::get(0)); + } else if (func->getReturnType()->isFloat()) { + pBuilder->createReturnInst(ConstantValue::get(0.0F)); + } else { + pBuilder->createReturnInst({}); + } + } + } + } + } } } // namespace sysy diff --git a/src/include/SysYIROptPre.h b/src/include/SysYIROptPre.h index 71a723d..db27b82 100644 --- a/src/include/SysYIROptPre.h +++ b/src/include/SysYIROptPre.h @@ -7,6 +7,9 @@ namespace sysy { // 优化前对SysY IR的预处理,也可以视作部分CFG优化 // 主要包括删除无用指令、合并基本块、删除空块等 +// 这些操作可以在SysY IR生成时就完成,但为了简化IR生成过程, +// 这里将其放在SysY IR生成后进行预处理 +// 同时兼容phi节点的处理,可以再mem2reg后再次调用优化 class SysYOptPre { private: Module *pModule; @@ -15,6 +18,13 @@ class SysYOptPre { public: SysYOptPre(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {} + void SysYOptimizateAfterIR(){ + SysYDelAfterBr(); + SysYBlockMerge(); + SysYDelNoPreBLock(); + SysYDelEmptyBlock(); + SysYAddReturn(); + } void SysYDelInstAfterBr(); // 删除br后面的指令 void SysYDelEmptyBlock(); // 空块删除 void SysYDelNoPreBLock(); // 删除无前驱块 From 10b43fc90d39ad3e384f1e36a4f54e477b3a52c7 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Mon, 23 Jun 2025 17:04:45 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8B=A5=E5=B9=B2bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CMakeLists.txt | 1 + src/SysYIROptPre.cpp | 37 ++++++++++++++++++------------------- src/include/SysYIROptPre.h | 4 ++-- src/sysyc.cpp | 5 +++++ 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8851182..f6f841a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable(sysyc SysYIRGenerator.cpp # Backend.cpp SysYIRPrinter.cpp + SysYIROptPre.cpp RISCv32Backend.cpp ) target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/src/SysYIROptPre.cpp b/src/SysYIROptPre.cpp index edd9333..90ff3fd 100644 --- a/src/SysYIROptPre.cpp +++ b/src/SysYIROptPre.cpp @@ -38,9 +38,8 @@ void SysYOptPre::SysYDelInstAfterBr() { 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++) { + for (auto iter = instructions.begin(); iter != instructions.end(); ++iter) { if (Branch) usedelete(iter->get()); else if ((*iter)->isTerminator()){ @@ -48,8 +47,8 @@ void SysYOptPre::SysYDelInstAfterBr() { Branchiter = iter; } } - Branchiter++; - while(Branchiter != instructions->begin()) + if (Branchiter != instructions.end()) ++Branchiter; + while (Branchiter != instructions.end()) Branchiter = instructions.erase(Branchiter); if (Branch) { // 更新前驱后继关系 @@ -183,10 +182,8 @@ void SysYOptPre::SysYDelNoPreBLock() { } - for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();blockIter++) { + for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) { if (!blockIter->get()->getreachable()) { - //// 处理phi指令 - // 删除不可达基本块的phi指令的操作数 for (auto succblock : blockIter->get()->getSuccessors()) { int indexphi = 1; for (auto pred : succblock->getPredecessors()) { @@ -202,14 +199,16 @@ void SysYOptPre::SysYDelNoPreBLock() { phiinst->removeOperand(indexphi); } } - // 删除不可达基本块 - func->removeBasicBlock(blockIter->get()); + // 删除不可达基本块,注意迭代器不可达问题 + func->removeBasicBlock((blockIter++)->get()); + } else { + blockIter++; } } } } -void SysyOptimization::SysyDelEmptyBlock() { +void SysYOptPre::SysYDelEmptyBlock() { auto &functions = pModule->getFunctions(); for (auto &function : functions) { // 收集不可达基本块 @@ -259,7 +258,7 @@ void SysyOptimization::SysyDelEmptyBlock() { --thelastinst; // 根据br指令传递的后继块信息,跳过空块链 - if (thelastinst->get()->getKind()->isUnconditional()) { + if (thelastinst->get()->isUnconditional()) { BasicBlock* OldBrBlock = dynamic_cast(thelastinst->get()->getOperand(0)); BasicBlock *thelastBlockOld = nullptr; // 如果空块链表为多个块 @@ -285,7 +284,7 @@ void SysyOptimization::SysyDelEmptyBlock() { // 更新phi指令的操作数 // 移除thelastBlockOld对应的phi操作数 - for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { + for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { if (InstInNew->isPhi()) { dynamic_cast(InstInNew.get())->removeOperand(indexphi + 1); } else { @@ -322,12 +321,12 @@ void SysyOptimization::SysyDelEmptyBlock() { // auto indexInNew = dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors(). if (thelastBlockOld != nullptr) { - int index = 0; + int indexphi = 0; for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(1))->getPredecessors()) { if (pred == thelastBlockOld) { break; } - index++; + indexphi++; } for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(1))->getInstructions()) { @@ -362,12 +361,12 @@ void SysyOptimization::SysyDelEmptyBlock() { dynamic_cast(thelastinst->get()->getOperand(2))->addPredecessor(basicBlock.get()); if (thelastBlockOld != nullptr) { - int index = 0; + int indexphi = 0; for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(2))->getPredecessors()) { if (pred == thelastBlockOld) { break; } - index++; + indexphi++; } for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(2))->getInstructions()) { if (InstInNew->isPhi()) { @@ -398,12 +397,12 @@ void SysyOptimization::SysyDelEmptyBlock() { basicBlock->addSuccessor(dynamic_cast(thelastinst->get()->getOperand(0))); dynamic_cast(thelastinst->get()->getOperand(0))->addPredecessor(basicBlock.get()); if (thelastBlockOld != nullptr) { - int index = 0; + int indexphi = 0; for (auto &pred : dynamic_cast(thelastinst->get()->getOperand(0))->getPredecessors()) { if (pred == thelastBlockOld) { break; } - index++; + indexphi++; } for (auto &InstInNew : dynamic_cast(thelastinst->get()->getOperand(0))->getInstructions()) { @@ -461,7 +460,7 @@ void SysYOptPre::SysYAddReturn() { auto &functions = pModule->getFunctions(); for (auto &function : functions) { auto &func = function.second; - auto &basicBlocks = func->getBasicBlocks(); + auto basicBlocks = func->getBasicBlocks(); for (auto &block : basicBlocks) { if (block->getNumSuccessors() == 0) { // 如果基本块没有后继块,则添加一个返回指令 diff --git a/src/include/SysYIROptPre.h b/src/include/SysYIROptPre.h index db27b82..4f0bdca 100644 --- a/src/include/SysYIROptPre.h +++ b/src/include/SysYIROptPre.h @@ -19,7 +19,7 @@ class SysYOptPre { SysYOptPre(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {} void SysYOptimizateAfterIR(){ - SysYDelAfterBr(); + SysYDelInstAfterBr(); SysYBlockMerge(); SysYDelNoPreBLock(); SysYDelEmptyBlock(); @@ -31,7 +31,7 @@ class SysYOptPre { void SysYBlockMerge(); // 合并基本块(主要针对嵌套if while的exit块, // 也可以修改IR生成实现回填机制 void SysYAddReturn(); // 添加return指令(主要针对Void函数) - void usedelete(); // use删除 + void usedelete(Instruction *instr); // use删除 }; } // namespace sysy diff --git a/src/sysyc.cpp b/src/sysyc.cpp index dc1015b..854ac53 100644 --- a/src/sysyc.cpp +++ b/src/sysyc.cpp @@ -9,6 +9,7 @@ using namespace antlr4; // #include "Backend.h" #include "SysYIRGenerator.h" #include "SysYIRPrinter.h" +#include "SysYIROptPre.h" // #include "LLVMIRGenerator.h" using namespace sysy; @@ -79,6 +80,10 @@ int main(int argc, char **argv) { auto moduleIR = generator.get(); SysYPrinter printer(moduleIR); printer.printIR(); + auto builder = generator.getBuilder(); + SysYOptPre optPre(moduleIR, builder); + optPre.SysYOptimizateAfterIR(); + printer.printIR(); return EXIT_SUCCESS; } return EXIT_SUCCESS;