diff --git a/Pass_ID_List.md b/Pass_ID_List.md index 79de64c..14f3379 100644 --- a/Pass_ID_List.md +++ b/Pass_ID_List.md @@ -1,5 +1,6 @@ -# 记录中端遍的唯一标识ID +# 记录中端遍的开发进度 | 名称 | 优化级别 | 开发进度 | | ------------ | ------------ | ---------- | -| CFG优化 | 函数级 | 已完成 | \ No newline at end of file +| CFG优化 | 函数级 | 已完成 | +| DCE | 函数级 | 待测试 | \ No newline at end of file diff --git a/src/CFGOptPass.cpp b/src/CFGOptPass.cpp deleted file mode 100644 index 224a553..0000000 --- a/src/CFGOptPass.cpp +++ /dev/null @@ -1,706 +0,0 @@ -#include "CFGOptPass.h" // 包含新的 CFG 优化遍的头文件 -#include "Dom.h" // CFG修改会使支配树失效,包含头文件 -#include "IR.h" -#include "IRBuilder.h" -#include "Liveness.h" // CFG修改会使活跃变量分析失效,包含头文件 -#include "SysYIROptUtils.h" // 包含您提供的 SysYIROptUtils -#include -#include -#include -#include -#include -#include // For SysYDelNoPreBLock -#include - -namespace sysy { - -char CFGOptimizationPass::ID = 0; // 初始化静态 ID - -// 声明分析依赖和失效 -void CFGOptimizationPass::getAnalysisUsage(std::set &analysisDependencies, - std::set &analysisInvalidations) const { - // CFG 优化会改变控制流图,因此会使大部分数据流分析失效。 - // 特别是支配树和活跃变量分析。 - analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID); - analysisInvalidations.insert(&LivenessAnalysisPass::ID); - // TODO: 如果有其他分析(如数据流分析)也可能失效,需要在此处添加 -} - -// ====================================================================== -// 静态 CFG 优化辅助函数的实现 -// 大部分代码直接从您提供的 SysYIRCFGOpt.cpp 复制过来 -// 并根据新的 PhiInst 定义调整了 Phi 节点处理逻辑 -// ====================================================================== - -bool CFGOptimizationPass::SysYDelInstAfterBr(Function *func) { - bool changed = false; - // 使用迭代器安全的遍历,因为可能会删除指令 - for (auto &basicBlock : func->getBasicBlocks()) { - if (!basicBlock) - continue; // 确保基本块有效 - - bool terminatorFound = false; - auto terminatorIter = basicBlock->getInstructions().end(); // 迭代器指向终止指令 - - // 查找终止指令并标记其后的指令进行删除 - for (auto iter = basicBlock->getInstructions().begin(); iter != basicBlock->getInstructions().end(); ++iter) { - if (terminatorFound) { - // 如果已经找到终止指令,则当前指令是无用指令删除指令 - SysYIROptUtils::usedelete(iter->get()); - } else if ((*iter)->isTerminator()) { - terminatorFound = true; - terminatorIter = iter; - } - } - - // 删除终止指令后的所有指令 - if (terminatorFound) { - auto currentIter = std::next(terminatorIter); // 从终止指令的下一个开始删除 - while (currentIter != basicBlock->getInstructions().end()) { - changed = true; - currentIter = basicBlock->getInstructions().erase(currentIter); - } - } - - // 更新前驱后继关系:由于可能删除了旧的终止指令并改变了控制流 - // 最好是先清除旧的关系,然后根据最新的终止指令重新建立关系 - if (terminatorFound) { - Instruction *currentTerminator = - basicBlock->getInstructions().empty() ? nullptr : basicBlock->getInstructions().back().get(); - if (!currentTerminator || !currentTerminator->isTerminator()) { - // 这是一种错误情况,块应该总是以终止指令结束 - // 或者说,如果删除了唯一的终止指令,那么块就没有后继了,需要后续优化来修复 - // 暂时跳过更新,让其他优化(如 SysYAddReturn)来处理 - continue; - } - - // 清除旧的后继关系 - // 注意:这里需要复制一份后继列表,因为在循环中修改原列表会使迭代器失效 - std::vector oldSuccessors(basicBlock->getSuccessors().begin(), basicBlock->getSuccessors().end()); - for (BasicBlock *succ : oldSuccessors) { - if (succ) { - succ->removePredecessor(basicBlock.get()); - basicBlock->removeSuccessor(succ); - } - } - - // 根据最新的终止指令重新建立新的后继关系 - if (currentTerminator->isUnconditional()) { - BasicBlock *branchBlock = dynamic_cast(currentTerminator->getOperand(0)); - if (branchBlock) { - basicBlock->addSuccessor(branchBlock); - branchBlock->addPredecessor(basicBlock.get()); - } - } else if (currentTerminator->isConditional()) { - BasicBlock *thenBlock = dynamic_cast(currentTerminator->getOperand(1)); - BasicBlock *elseBlock = dynamic_cast(currentTerminator->getOperand(2)); - if (thenBlock) { - basicBlock->addSuccessor(thenBlock); - thenBlock->addPredecessor(basicBlock.get()); - } - if (elseBlock && thenBlock != elseBlock) { // 避免重复添加相同后继 - basicBlock->addSuccessor(elseBlock); - elseBlock->addPredecessor(basicBlock.get()); - } - } - } - } - return changed; -} - -bool CFGOptimizationPass::SysYBlockMerge(Function *func) { - bool changed = false; - - // 使用迭代器安全的循环来遍历和删除 - for (auto blockiter = func->getBasicBlocks().begin(); blockiter != func->getBasicBlocks().end();) { - BasicBlock *currentBlock = blockiter->get(); - if (!currentBlock) { // 防止空指针 - ++blockiter; - continue; - } - - // 入口块不能被合并到前一个块(它没有前一个块),但可以作为目标块被合并 - if (currentBlock == func->getEntryBlock() && currentBlock->getNumPredecessors() == 0) { - ++blockiter; - continue; - } - - // 如果当前块只有一个后继块 - if (currentBlock->getNumSuccessors() == 1) { - BasicBlock *nextBlock = currentBlock->getSuccessors()[0]; - if (!nextBlock) { // 后继块无效 - ++blockiter; - continue; - } - - // 且后继块只有一个前驱块(这是合并的条件之一) - if (nextBlock->getNumPredecessors() == 1 && nextBlock->getPredecessors()[0] == currentBlock) { - // std::cout << "merge block: " << currentBlock->getName() << " with " << nextBlock->getName() << std::endl; - - // 删除 currentBlock 最后的 br 指令 - if (!currentBlock->getInstructions().empty()) { - Instruction *lastInst = currentBlock->getInstructions().back().get(); - if (lastInst->isTerminator()) { - SysYIROptUtils::usedelete(lastInst); - // 从指令列表中移除 - currentBlock->getInstructions().pop_back(); - } - } - - // 处理 Phi 指令: - // 如果 nextBlock 包含 Phi 指令,需要将这些 Phi 指令的操作数进行处理 - // 因为 nextBlock 的唯一前驱是 currentBlock,这些 Phi 指令在合并后变得多余。 - // 它们的值可以直接替换为来自 currentBlock 的值。 - // 然后删除这些 Phi 指令。 - auto nextBlockInstIter = nextBlock->getInstructions().begin(); - while (nextBlockInstIter != nextBlock->getInstructions().end()) { - if ((*nextBlockInstIter)->isPhi()) { - PhiInst *phi = dynamic_cast(nextBlockInstIter->get()); - if (phi) { - // 找到 Phi 对应 currentBlock 的传入值 - Value *incomingVal = phi->getvalfromBlk(currentBlock); - if (incomingVal) { - phi->replaceAllUsesWith(incomingVal); // 替换所有使用 - SysYIROptUtils::usedelete(phi); // 删除 phi 指令 - nextBlockInstIter = nextBlock->getInstructions().erase(nextBlockInstIter); - changed = true; - continue; // 继续检查下一个指令 - } - } - } else { - break; // Phi 指令总是在基本块的开头 - } - ++nextBlockInstIter; - } - - // 将 nextBlock 的指令移动到 currentBlock - for (auto institer = nextBlock->begin(); institer != nextBlock->end();) { - institer->get()->setParent(currentBlock); - currentBlock->getInstructions().emplace_back(institer->release()); // 移动 unique_ptr - institer = nextBlock->getInstructions().erase(institer); - } - - // 合并参数 (如果 nextBlock 有 Arguments) - for (auto &argm : nextBlock->getArguments()) { - argm->setParent(currentBlock); // 更新父指针 - currentBlock->insertArgument(argm); // 将参数插入到 currentBlock - } - nextBlock->getArguments().clear(); // 清空 nextBlock 的参数列表 - - // 更新前驱后继关系 - // 清理 nextBlock 与 currentBlock 之间的关系 - currentBlock->removeSuccessor(nextBlock); - nextBlock->removePredecessor(currentBlock); - - // 将 nextBlock 的所有后继转移到 currentBlock - std::vector nextBlockSuccessors(nextBlock->getSuccessors().begin(), - nextBlock->getSuccessors().end()); - for (BasicBlock *succ : nextBlockSuccessors) { - if (succ) { - currentBlock->addSuccessor(succ); - succ->replacePredecessor(nextBlock, currentBlock); // 更新后继块的前驱 - nextBlock->removeSuccessor(succ); // 从 nextBlock 移除,避免重复处理 - } - } - - // 从函数中删除 nextBlock - func->removeBasicBlock(nextBlock); - changed = true; - // 保持 blockiter 不变,以便在下一次循环中重新检查当前的 currentBlock - // 因为它的新后继可能现在又满足合并条件了 - } else { - ++blockiter; // 不满足合并条件,移动到下一个块 - } - } else { - ++blockiter; // 不满足合并条件,移动到下一个块 - } - } - return changed; -} - -bool CFGOptimizationPass::SysYDelNoPreBLock(Function *func) { - bool changed = false; - - // 标记所有块为不可达 - for (auto &block_ptr : func->getBasicBlocks()) { - if (block_ptr) - block_ptr->setreachableFalse(); - } - - // 从入口块开始进行可达性分析 (BFS) - BasicBlock *entryBlock = func->getEntryBlock(); - if (!entryBlock) - return false; // 没有入口块,则无需处理 - - entryBlock->setreachableTrue(); - std::queue blockqueue; - blockqueue.push(entryBlock); - while (!blockqueue.empty()) { - BasicBlock *block = blockqueue.front(); - blockqueue.pop(); - if (block) { - for (auto &succ : block->getSuccessors()) { - if (succ && !succ->getreachable()) { - succ->setreachableTrue(); - blockqueue.push(succ); - } - } - } - } - - // 遍历所有块,删除不可达块 - - for (auto blockIter = func->getBasicBlocks_NoRange().begin(); blockIter != func->getBasicBlocks_NoRange().end();) { - BasicBlock *currentBlock = blockIter->get(); - if (!currentBlock) { - // 如果当前块是空指针,直接跳过 - blockIter = func->getBasicBlocks_NoRange().erase(blockIter); - changed = true; - continue; - } - - if (!currentBlock->getreachable()) { - // 入口块不可删除 - if (currentBlock == func->getEntryBlock()) { - ++blockIter; - continue; - } - - // 删除不可达基本块内的所有指令 - // 由于 usedelete 会从父块中移除指令,这里直接遍历并调用即可 - auto instsToProcess = currentBlock->getInstructions(); // 复制一份,避免迭代器失效 - for (auto &iterInst_ptr : instsToProcess) { - if (iterInst_ptr) - SysYIROptUtils::usedelete(iterInst_ptr.get()); - } - - // 处理 Phi 指令:移除指向该不可达块的 Phi 操作数 - // 遍历所有后继块的 Phi 指令,移除与 currentBlock 相关的传入值 - std::vector successorsCopy(currentBlock->getSuccessors().begin(), - currentBlock->getSuccessors().end()); - for (BasicBlock *succblock : successorsCopy) { - if (!succblock) - continue; - // 遍历后继块的指令,只处理 Phi 指令(它们在块的开头) - for (auto &phiinst_ptr : succblock->getInstructions()) { - if (phiinst_ptr->getKind() != Instruction::kPhi) { - break; // Phi 指令都在块的开头 - } - PhiInst *phi = dynamic_cast(phiinst_ptr.get()); - if (phi) { - // 使用 PhiInst 的 delBlk 方法来移除与当前被删除块相关的传入值 - phi->delBlk(currentBlock); - } - } - // 更新后继块的前驱列表 (非常重要,因为 currentBlock 要被删除了) - succblock->removePredecessor(currentBlock); - } - // 清空 currentBlock 的后继,因为它将不复存在 - currentBlock->clearPredecessors(); // 清空前驱列表 - currentBlock->clearSuccessors(); // 清空后继列表 - - // 从函数中删除基本块 - blockIter = func->getBasicBlocks_NoRange().erase(blockIter); - changed = true; - } else { - ++blockIter; - } - } - return changed; -} - -bool CFGOptimizationPass::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) { - bool changed = false; - - // 收集所有“空”基本块(没有实际指令,或只有Phi和UncondBr)及其目标 - // map: 空块 -> 其唯一后继 (如果存在) - std::map EmptyBlocksMap; - - // 第一次遍历:识别空块及其跳转目标 - for (auto &basicBlock_ptr : func->getBasicBlocks()) { - BasicBlock *basicBlock = basicBlock_ptr.get(); - if (!basicBlock) - continue; - - // 判断是否是空块:没有指令或者只有 Phi 和一个终止指令 - bool isEmptyCandidate = true; - Instruction *terminatorInst = nullptr; - - if (basicBlock->getNumInstructions() == 0) { - isEmptyCandidate = true; // 完全空块 - } else { - // 检查除了最后一个指令之外是不是只有phi指令 - for(auto &inst_ptr : basicBlock->getInstructions()) { - Instruction *inst = inst_ptr.get(); - if (!inst->isPhi() && !inst->isTerminator()) { - isEmptyCandidate = false; // 有其他类型的指令 - break; - } - } - // for (size_t i = 0; i < basicBlock->getNumInstructions(); ++i) { - // Instruction *inst = basicBlock->getInstructions()[i].get(); - // if (inst->isTerminator()) { - // terminatorInst = inst; - // // 如果终止指令不是最后一个,那这个块有问题 - // if (i != basicBlock->getNumInstructions() - 1) { - // isEmptyCandidate = false; - // break; - // } - // } else if (!inst->isPhi()) { // 除了 phi 和终止指令,还有其他指令 - // isEmptyCandidate = false; - // break; - // } - // } - } - - if (isEmptyCandidate) { - if (terminatorInst && terminatorInst->isUnconditional()) { - if (basicBlock->getNumSuccessors() == 1) { // 只有一条无条件跳转 - EmptyBlocksMap[basicBlock] = dynamic_cast(terminatorInst->getOperand(0)); - } - } else if (!terminatorInst && basicBlock->getNumSuccessors() == 1) { - // 可能是完全空块,但没有终止指令,只有一个后继(需要IRBuilder补全) - // 这种情况下,它也构成空块链的一部分 - EmptyBlocksMap[basicBlock] = basicBlock->getSuccessors().front(); - } - // 如果是条件分支,不认为是“空块链”的中间节点 - } - } - - // 第二次遍历:更新前驱的跳转目标,跳过空块链 - for (auto &basicBlock_ptr : func->getBasicBlocks()) { - BasicBlock *basicBlock = basicBlock_ptr.get(); - if (!basicBlock) - continue; - - // EntryBlock 不参与空块链的删除,但可以重定向其内部跳转 - if (basicBlock == func->getEntryBlock() && EmptyBlocksMap.count(basicBlock)) { - // 如果入口块本身是空块,处理其跳转目标 - Instruction *lastInst = - basicBlock->getInstructions().empty() ? nullptr : basicBlock->getInstructions().back().get(); - if (lastInst && lastInst->isUnconditional()) { - BasicBlock *oldTargetBlock = dynamic_cast(lastInst->getOperand(0)); - BasicBlock *currentTargetBlock = oldTargetBlock; - while (EmptyBlocksMap.count(currentTargetBlock)) { - currentTargetBlock = EmptyBlocksMap[currentTargetBlock]; - } - if (currentTargetBlock != oldTargetBlock) { - changed = true; - // 更新前驱后继关系 - basicBlock->removeSuccessor(oldTargetBlock); - oldTargetBlock->removePredecessor(basicBlock); - - lastInst->replaceOperand(0, currentTargetBlock); - basicBlock->addSuccessor(currentTargetBlock); - currentTargetBlock->addPredecessor(basicBlock); - - // 处理 Phi 指令:将被跳过的空块替换为 currentBlock - for (auto &InstInNew_ptr : currentTargetBlock->getInstructions()) { - if (InstInNew_ptr->isPhi()) { - PhiInst *phi = dynamic_cast(InstInNew_ptr.get()); - if (phi) { - // 使用 replaceold2new 替换 phi 传入的基本块 - phi->replaceold2new(oldTargetBlock, basicBlock); - } - } else { - break; - } - } - } - } - continue; - } - - // 确保块有终止指令,如果没有,添加一个(防止后续处理崩溃) - // 这种情况通常发生在IR生成时没有为完全空的块插入跳转,或者前面优化删除了终止指令 - if (basicBlock->getNumInstructions() == 0 || !basicBlock->getInstructions().back()->isTerminator()) { - if (basicBlock->getNumSuccessors() == 1) { - pBuilder->setPosition(basicBlock, basicBlock->end()); - pBuilder->createUncondBrInst(basicBlock->getSuccessors()[0], {}); - changed = true; // 添加了指令,所以有变化 - } - } - - auto lastInst = basicBlock->getInstructions().end(); - if (lastInst == basicBlock->getInstructions().begin()) { // 块是空的 - continue; - } - --lastInst; // 指向最后一个指令 - - if ((*lastInst)->isUnconditional()) { - BasicBlock *oldTargetBlock = dynamic_cast((*lastInst)->getOperand(0)); - BasicBlock *currentTargetBlock = oldTargetBlock; - - // 沿空块链查找最终目标 - while (EmptyBlocksMap.count(currentTargetBlock) && currentTargetBlock != func->getEntryBlock()) { - // 防止无限循环或将EntryBlock也视为空块 - currentTargetBlock = EmptyBlocksMap[currentTargetBlock]; - } - - if (currentTargetBlock != oldTargetBlock) { // 如果目标改变了 - changed = true; - // 更新前驱后继关系 - basicBlock->removeSuccessor(oldTargetBlock); - oldTargetBlock->removePredecessor(basicBlock); - - (*lastInst)->replaceOperand(0, currentTargetBlock); - basicBlock->addSuccessor(currentTargetBlock); - currentTargetBlock->addPredecessor(basicBlock); - - // 更新 Phi 指令:将被跳过的空块替换为 currentBlock - for (auto &InstInNew_ptr : currentTargetBlock->getInstructions()) { - if (InstInNew_ptr->isPhi()) { - PhiInst *phi = dynamic_cast(InstInNew_ptr.get()); - if (phi) { - // 使用 replaceold2new 替换 phi 传入的基本块 - phi->replaceold2new(oldTargetBlock, basicBlock); - } - } else { - break; - } - } - } - } else if ((*lastInst)->isConditional()) { - BasicBlock *oldThenBlock = dynamic_cast((*lastInst)->getOperand(1)); - BasicBlock *oldElseBlock = dynamic_cast((*lastInst)->getOperand(2)); - - BasicBlock *currentThenBlock = oldThenBlock; - BasicBlock *currentElseBlock = oldElseBlock; - - // 沿空块链查找最终目标 - while (EmptyBlocksMap.count(currentThenBlock) && currentThenBlock != func->getEntryBlock()) { - currentThenBlock = EmptyBlocksMap[currentThenBlock]; - } - while (EmptyBlocksMap.count(currentElseBlock) && currentElseBlock != func->getEntryBlock()) { - currentElseBlock = EmptyBlocksMap[currentElseBlock]; - } - - bool thenChanged = (currentThenBlock != oldThenBlock); - bool elseChanged = (currentElseBlock != oldElseBlock); - - if (thenChanged || elseChanged) { - changed = true; - // 更新前驱后继关系和 Phi 指令 - if (thenChanged) { - basicBlock->removeSuccessor(oldThenBlock); - oldThenBlock->removePredecessor(basicBlock); - (*lastInst)->replaceOperand(1, currentThenBlock); - basicBlock->addSuccessor(currentThenBlock); - currentThenBlock->addPredecessor(basicBlock); - - for (auto &InstInNew_ptr : currentThenBlock->getInstructions()) { - if (InstInNew_ptr->isPhi()) { - PhiInst *phi = dynamic_cast(InstInNew_ptr.get()); - if (phi) - phi->replaceold2new(oldThenBlock, basicBlock); - } else { - break; - } - } - } - if (elseChanged) { - basicBlock->removeSuccessor(oldElseBlock); - oldElseBlock->removePredecessor(basicBlock); - (*lastInst)->replaceOperand(2, currentElseBlock); - basicBlock->addSuccessor(currentElseBlock); - currentElseBlock->addPredecessor(basicBlock); - - for (auto &InstInNew_ptr : currentElseBlock->getInstructions()) { - if (InstInNew_ptr->isPhi()) { - PhiInst *phi = dynamic_cast(InstInNew_ptr.get()); - if (phi) - phi->replaceold2new(oldElseBlock, basicBlock); - } else { - break; - } - } - } - - // 处理 then 和 else 分支合并的情况 - if (currentThenBlock == currentElseBlock) { - SysYIROptUtils::usedelete(lastInst->get()); - basicBlock->getInstructions().erase(lastInst); - pBuilder->setPosition(basicBlock, basicBlock->end()); - pBuilder->createUncondBrInst(currentThenBlock, {}); - changed = true; - } - } - } - } - - // 第三次遍历:删除所有识别出来的空块 - for (auto iter = func->getBasicBlocks_NoRange().begin(); iter != func->getBasicBlocks_NoRange().end();) { - BasicBlock *currentBlock = iter->get(); - if (!currentBlock) { - iter = func->getBasicBlocks_NoRange().erase(iter); - changed = true; - continue; - } - - if (EmptyBlocksMap.count(currentBlock)) { - // EntryBlock 不能被删除 - if (currentBlock == func->getEntryBlock()) { - ++iter; - continue; - } - - // 删除空块内的所有指令 - auto instsToProcess = currentBlock->getInstructions(); // 复制一份 - for (auto &iterInst_ptr : instsToProcess) { - if (iterInst_ptr) - SysYIROptUtils::usedelete(iterInst_ptr.get()); - } - - // 更新其后继的前驱关系(如果之前没有完全清除,但由于 replaceold2new 已经处理了大部分) - // 这里主要为了确保被删除块的所有后继都移除了它作为前驱 - std::vector succsCopy(currentBlock->getSuccessors().begin(), currentBlock->getSuccessors().end()); - for (BasicBlock *succ : succsCopy) { - if (succ) - succ->removePredecessor(currentBlock); - } - // 清空其自身的前驱和后继 - currentBlock->getPredecessors().clear(); - currentBlock->getSuccessors().clear(); - - // 从函数中删除基本块 - iter = func->getBasicBlocks_NoRange().erase(iter); // erase 会返回下一个有效迭代器 - changed = true; - } else { - ++iter; - } - } - return changed; -} - -bool CFGOptimizationPass::SysYAddReturn(Function *func, IRBuilder *pBuilder) { - bool changed = false; - // 使用新的迭代器方式遍历 - for (auto &block_ptr : func->getBasicBlocks()) { - BasicBlock *block = block_ptr.get(); - if (!block) - continue; // 确保基本块有效 - - // 如果基本块没有后继(即是出口块) - if (block->getNumSuccessors() == 0) { - // 检查最后一个指令是否是返回指令 - if (block->getNumInstructions() == 0 || !block->getInstructions().back()->isReturn()) { - changed = true; - pBuilder->setPosition(block, block->end()); - if (func->getReturnType()->isInt()) { - pBuilder->createReturnInst(ConstantInteger::get(0)); - } else if (func->getReturnType()->isFloat()) { - pBuilder->createReturnInst(ConstantFloating::get(0.0F)); - } else { // Void 类型 - pBuilder->createReturnInst(); - } - } - } - } - return changed; -} - -bool CFGOptimizationPass::SysYCondBr2Br(Function *func, IRBuilder *pBuilder) { - bool changed = false; - - for (auto &basicblock_ptr : func->getBasicBlocks()) { - BasicBlock *basicblock = basicblock_ptr.get(); - if (!basicblock || basicblock->getNumInstructions() == 0) - continue; - - auto lastInstIter = basicblock->getInstructions().end(); - --lastInstIter; // 指向最后一个指令 - - if ((*lastInstIter)->isConditional()) { - Value *condOperand = (*lastInstIter)->getOperand(0); - ConstantValue *constOperand = dynamic_cast(condOperand); - - if (constOperand != nullptr) { // 条件操作数是常量 - changed = true; - - BasicBlock *thenBlock = dynamic_cast((*lastInstIter)->getOperand(1)); - BasicBlock *elseBlock = dynamic_cast((*lastInstIter)->getOperand(2)); - - // 删除旧的条件分支指令 - SysYIROptUtils::usedelete(lastInstIter->get()); - basicblock->getInstructions().erase(lastInstIter); - - BasicBlock *targetBlock = nullptr; - BasicBlock *prunedBlock = nullptr; // 被剪枝的路径的块 - - bool isTrue = false; - if (constOperand->isFloat()) { - isTrue = (constOperand->getFloat() != 0.0F); - } else { // 整数 - isTrue = (constOperand->getInt() != 0); - } - - if (isTrue) { - targetBlock = thenBlock; - prunedBlock = elseBlock; - } else { - targetBlock = elseBlock; - prunedBlock = thenBlock; - } - - // 创建无条件跳转指令 - pBuilder->setPosition(basicblock, basicblock->end()); - pBuilder->createUncondBrInst(targetBlock, {}); - - // 更新前驱后继关系 - // 移除被剪枝的路径 - if (prunedBlock && basicblock->hasSuccessor(prunedBlock)) { - basicblock->removeSuccessor(prunedBlock); - prunedBlock->removePredecessor(basicblock); - - // 移除被剪枝路径上的 Phi 指令操作数 - for (auto &phiinst_ptr : prunedBlock->getInstructions()) { - if (phiinst_ptr->getKind() != Instruction::kPhi) { - break; - } - PhiInst *phi = dynamic_cast(phiinst_ptr.get()); - if (phi) { - // 使用 PhiInst 的 delBlk 方法来移除与当前 basicblock 相关的传入值 - phi->delBlk(basicblock); - } - } - } - } - } - } - return changed; -} - -// ====================================================================== -// CFGOptimizationPass::runOnFunction 实现 -// ====================================================================== - -bool CFGOptimizationPass::runOnFunction(Function *F, AnalysisManager &AM) { - bool changed = false; - if (!F) - return false; - - // 创建一个临时的 IRBuilder 实例,用于在当前函数内创建指令 - IRBuilder builder(nullptr); - // 迭代进行 CFG 优化,直到不再发生变化 - bool funcChangedThisIteration = true; - while (funcChangedThisIteration) { - funcChangedThisIteration = false; // 每次循环开始时重置为 false - - // 这里的顺序很重要,某些优化依赖于其他优化(例如删除无前驱块) - // 并且某些优化可能会为其他优化创造机会,所以需要循环直到稳定 - funcChangedThisIteration |= SysYCondBr2Br(F, &builder); // 条件分支转换为无条件分支 - funcChangedThisIteration |= SysYDelInstAfterBr(F); // 删除 br 后的无用指令 - funcChangedThisIteration |= SysYDelEmptyBlock(F, &builder); // 删除空块(可能涉及跳转目标更新) - funcChangedThisIteration |= SysYDelNoPreBLock(F); // 删除无前驱块(不可达块) - funcChangedThisIteration |= SysYBlockMerge(F); // 合并基本块 - funcChangedThisIteration |= SysYAddReturn(F, &builder); // 添加返回指令 - - // 如果本轮有任何变化,则继续下一次循环 - changed = changed || funcChangedThisIteration; - } - - // 如果函数有任何变化,返回 true - return changed; -} - -} // namespace sysy \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d82e1e3..01f54d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,7 +25,7 @@ add_executable(sysyc Pass.cpp Dom.cpp Liveness.cpp - # DeadCodeElimination.cpp + DCE.cpp AddressCalculationExpansion.cpp # Mem2Reg.cpp # Reg2Mem.cpp diff --git a/src/DCE.cpp b/src/DCE.cpp new file mode 100644 index 0000000..e0e9519 --- /dev/null +++ b/src/DCE.cpp @@ -0,0 +1,91 @@ +#include "DCE.h" +#include "IR.h" +#include "SysYIROptUtils.h" +#include +#include + +namespace sysy { + +// DCE 遍的静态 ID +void *DCE::ID = (void *)&DCE::ID; + +// DCE 遍的 runOnFunction 方法实现 +bool DCE::runOnFunction(Function *func, AnalysisManager &AM) { + alive_insts.clear(); + bool changed = false; + + auto basicBlocks = func->getBasicBlocks(); + + for (auto &basicBlock : basicBlocks) { + // 确保基本块有效 + if (!basicBlock) + continue; + for (auto &inst : basicBlock->getInstructions()) { + // 确保指令有效 + if (!inst) + continue; + if (isAlive(inst.get())) { + addAlive(inst.get()); + } + } + } + + // 第二遍:删除所有未被标记为活跃的指令。 + for (auto &basicBlock : basicBlocks) { + if (!basicBlock) + continue; + // 使用传统的迭代器循环,并手动管理迭代器, + // 以便在删除元素后正确前进。 + for (auto instIter = basicBlock->getInstructions().begin(); instIter != basicBlock->getInstructions().end();) { + auto &inst = *instIter; + Instruction *currentInst = inst.get(); + // 如果指令不在活跃集合中,则删除它。 + // 分支和返回指令由 isAlive 处理,并会被保留。 + if (alive_insts.count(currentInst) == 0) { + // 删除指令 + changed = true; // 标记 IR 已被修改 + SysYIROptUtils::usedelete(currentInst); + instIter = basicBlock->getInstructions().erase(instIter); // 删除后返回下一个迭代器 + } else { + ++instIter; // 指令活跃,移动到下一个 + } + } + } + + return changed; +} + +// 判断指令是否是“天然活跃”的实现 +// 只有具有副作用的指令(如存储、函数调用、原子操作) +// 和控制流指令(如分支、返回)是天然活跃的。 +bool DCE::isAlive(Instruction *inst) { + // TODO: 后续程序并发考虑原子操作 + // 其结果不被其他指令使用的指令(例如 StoreInst, BranchInst, ReturnInst)。 + // dynamic_cast(inst) 检查是否是函数调用指令, + // 函数调用通常有副作用。 + // 终止指令 (BranchInst, ReturnInst) 必须是活跃的,因为它控制了程序的执行流程。 + bool isBranchOrReturn = inst->isBranch() || inst->isReturn(); + bool isCall = inst->isCall(); + bool isStoreOrMemset = inst->isStore() && inst->isMemset(); + return isBranchOrReturn || isCall || isStoreOrMemset; +} + +// 递归地将活跃指令及其依赖加入到 alive_insts 集合中 +void DCE::addAlive(Instruction *inst) { + // 如果指令已经存在于活跃集合中,则无需重复处理 + if (alive_insts.count(inst) > 0) { + return; + } + // 将当前指令标记为活跃 + alive_insts.insert(inst); + // 遍历当前指令的所有操作数 + for (auto operand : inst->getOperands()) { + // 如果操作数是一个指令(即它是一个值的定义), + // 并且它还没有被标记为活跃 + if (auto opInst = dynamic_cast(operand->getValue())) { + addAlive(opInst); // 递归地将操作数指令标记为活跃 + } + } +} + +} // namespace sysy diff --git a/src/Pass.cpp b/src/Pass.cpp index 6a6f85b..bba8e36 100644 --- a/src/Pass.cpp +++ b/src/Pass.cpp @@ -2,6 +2,7 @@ #include "Liveness.h" #include "SysYIRCFGOpt.h" #include "SysYIRPrinter.h" +#include "DCE.h" #include "Pass.h" #include #include @@ -44,39 +45,30 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR registerOptimizationPass(builderIR); if (optLevel >= 1) { - if (DEBUG) std::cout << "Applying -O1 optimizations.\n"; + //经过设计安排优化遍的执行顺序以及执行逻辑 + if (DEBUG) std::cout << "Applying -O1 optimizations.\n"; + if (DEBUG) std::cout << "--- Running custom optimization sequence ---\n"; - // 只添加优化遍的 ID - this->addPass(&SysYDelInstAfterBrPass::ID); - this->addPass(&SysYDelNoPreBLockPass::ID); - this->addPass(&SysYBlockMergePass::ID); - this->addPass(&SysYDelEmptyBlockPass::ID); - this->addPass(&SysYCondBr2BrPass::ID); - this->addPass(&SysYAddReturnPass::ID); + this->clearPasses(); + this->addPass(&SysYDelInstAfterBrPass::ID); + this->addPass(&SysYDelNoPreBLockPass::ID); + this->addPass(&SysYBlockMergePass::ID); + this->addPass(&SysYDelEmptyBlockPass::ID); + this->addPass(&SysYCondBr2BrPass::ID); + this->addPass(&SysYAddReturnPass::ID); + this->run(); + + this->clearPasses(); + this->addPass(&DCE::ID); + this->run(); + + if (DEBUG) std::cout << "--- Custom optimization sequence finished ---\n"; } // 2. 创建遍管理器 // 3. 根据优化级别添加不同的优化遍 // TODO : 根据 optLevel 添加不同的优化遍 // 讨论 是不动点迭代进行优化遍还是手动客制化优化遍的顺序? - if (optLevel >= 1) { - if (DEBUG) std::cout << "Applying -O1 optimizations.\n"; - - // 4. 循环执行遍,直到 IR 稳定 (不再有任何遍修改 IR) - bool changed_in_iteration = true; - int iteration_count = 0; - while(changed_in_iteration) { - iteration_count++; - if (DEBUG) std::cout << "Optimization iteration: " << iteration_count << std::endl; - changed_in_iteration = run(); // 运行一次所有添加到 PassManager 的遍 - if (DEBUG && changed_in_iteration) { - std::cout << "=== IR after iteration " << iteration_count << " ===\n"; - SysYPrinter printer_iter(moduleIR); - printer_iter.printIR(); - } - } - if (DEBUG) std::cout << "Optimizations stabilized after " << iteration_count << " iterations.\n"; - } if (DEBUG) { @@ -86,6 +78,10 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR } } +void PassManager::clearPasses() { + passes.clear(); +} + void PassManager::addPass(void *passID) { PassRegistry ®istry = PassRegistry::getPassRegistry(); diff --git a/src/SysYIRCFGOpt.cpp b/src/SysYIRCFGOpt.cpp index 63d67d4..1a6c3a1 100644 --- a/src/SysYIRCFGOpt.cpp +++ b/src/SysYIRCFGOpt.cpp @@ -167,14 +167,14 @@ bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) { // 删除不可达基本块指令 for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end(); blockIter++) { - if (!blockIter->get()->getreachable()) { - for (auto instIter = blockIter->get()->getInstructions().begin(); - instIter != blockIter->get()->getInstructions().end();) { - SysYIROptUtils::usedelete(instIter->get()); - instIter = blockIter->get()->getInstructions().erase(instIter); + if (!blockIter->get()->getreachable()) { + for (auto instIter = blockIter->get()->getInstructions().begin(); + instIter != blockIter->get()->getInstructions().end();) { + SysYIROptUtils::usedelete(instIter->get()); + instIter = blockIter->get()->getInstructions().erase(instIter); + } } } -} for (auto blockIter = func->getBasicBlocks().begin(); blockIter != func->getBasicBlocks().end();) { diff --git a/src/include/CFGOptPass.h b/src/include/CFGOptPass.h deleted file mode 100644 index d4c4f8e..0000000 --- a/src/include/CFGOptPass.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "Pass.h" // 包含 Pass 框架 -#include "IR.h" // 包含 IR 定义 -#include "IRBuilder.h" // 包含 IRBuilder - -namespace sysy { - -// 前向声明 IRBuilder (如果在其他地方定义,确保路径正确) -// class IRBuilder; // 如果IRBuilder不在IRBuilder.h中定义,需要前向声明 - -// CFG 优化遍 -class CFGOptimizationPass : public OptimizationPass { -public: - // 唯一的 Pass ID - static char ID; - - CFGOptimizationPass() : OptimizationPass("CFGOptimization", Pass::Granularity::Function) {} - - // 实现 getPassID - void* getPassID() const override { return &ID; } - - // 声明分析依赖和失效 - void getAnalysisUsage(std::set& analysisDependencies, std::set& analysisInvalidations) const override; - - // 运行优化,现在接受 AnalysisManager& AM 参数 - bool runOnFunction(Function* F, AnalysisManager& AM) override; - -private: - // 将原 SysYCFGOpt 中的静态方法移入或直接使用 - // 这些方法可以直接声明为静态成员函数,并在 runOnFunction 中调用 - static bool SysYDelInstAfterBr(Function *func); - static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); - static bool SysYDelNoPreBLock(Function *func); - static bool SysYBlockMerge(Function *func); - static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); - static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); -}; - -} // namespace sysy \ No newline at end of file diff --git a/src/include/DCE.h b/src/include/DCE.h new file mode 100644 index 0000000..8be40bd --- /dev/null +++ b/src/include/DCE.h @@ -0,0 +1,46 @@ +#pragma once + +#include "IR.h" // 包含IR相关的定义,如Instruction, Function, BasicBlock等 +#include "IRBuilder.h" // 包含IR构建器的定义 +#include "SysYIROptUtils.h" // 包含SysY IR优化工具类的 +#include "Liveness.h" +#include "Dom.h" // 包含支配树的定义 +#include "Pass.h" // 包含Pass的基类定义 +#include // 用于存储活跃指令 + +namespace sysy { + +// DCE 优化遍类,继承自 OptimizationPass +class DCE : public OptimizationPass { + private: + std::unordered_set alive_insts; + // 判断指令是否是“天然活跃”的(即总是保留的) + // inst: 要检查的指令 + // 返回值: 如果指令是天然活跃的,则为true,否则为false + bool isAlive(Instruction *inst); + // 递归地将活跃指令及其依赖加入到 alive_insts 集合中 + // inst: 要标记为活跃的指令 + void addAlive(Instruction *inst); +public: + static void *ID; + DCE() : OptimizationPass("DCE", Granularity::Function) {} + bool runOnFunction(Function *func, AnalysisManager &AM) override; + void getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const override{ + // DCE不依赖特定的分析结果,它通过遍历和副作用判断来工作。 + + // DCE会删除指令,这会影响许多分析结果。 + // 至少,它会影响活跃性分析、支配树、控制流图(如果删除导致基本块为空并被合并)。 + // 假设存在LivenessAnalysisPass和DominatorTreeAnalysisPass + // analysisInvalidations.insert(&LivenessAnalysisPass::ID); + // analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID); + // 任何改变IR结构的优化,都可能导致通用分析(如活跃性、支配树、循环信息)失效。 + // 最保守的做法是使所有函数粒度的分析失效,或者只声明你明确知道会受影响的分析。 + // 考虑到这个DCE仅删除指令,如果它不删除基本块,CFG可能不变,但数据流分析会失效。 + // 对于更激进的DCE(如ADCE),CFG也会改变。 + // 这里我们假设它主要影响数据流分析,并且可能间接影响CFG相关分析。 + // 如果有SideEffectInfo,它也可能被修改,但通常SideEffectInfo是静态的,不因DCE而变。 + } + void *getPassID() const override { return &ID; } +}; + +} // namespace sysy \ No newline at end of file diff --git a/src/include/Pass.h b/src/include/Pass.h index b928b91..d387e9e 100644 --- a/src/include/Pass.h +++ b/src/include/Pass.h @@ -291,6 +291,7 @@ public: AnalysisManager &getAnalysisManager() { return analysisManager; } + void clearPasses(); }; // ====================================================================== diff --git a/src/include/SysYIRCFGOpt.h b/src/include/SysYIRCFGOpt.h index 4d025c8..f388138 100644 --- a/src/include/SysYIRCFGOpt.h +++ b/src/include/SysYIRCFGOpt.h @@ -54,6 +54,7 @@ public: static void *ID; SysYDelEmptyBlockPass(IRBuilder *builder) : OptimizationPass("SysYDelEmptyBlockPass", Granularity::Function), pBuilder(builder) {} bool runOnFunction(Function *F, AnalysisManager& AM) override; + void getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const override; void *getPassID() const override { return &ID; } }; @@ -62,6 +63,7 @@ public: static void *ID; SysYDelNoPreBLockPass() : OptimizationPass("SysYDelNoPreBLockPass", Granularity::Function) {} bool runOnFunction(Function *F, AnalysisManager& AM) override; + void getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const override; void *getPassID() const override { return &ID; } }; @@ -70,6 +72,7 @@ public: static void *ID; SysYBlockMergePass() : OptimizationPass("SysYBlockMergePass", Granularity::Function) {} bool runOnFunction(Function *F, AnalysisManager& AM) override; + void getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const override; void *getPassID() const override { return &ID; } }; @@ -80,6 +83,7 @@ public: static void *ID; SysYAddReturnPass(IRBuilder *builder) : OptimizationPass("SysYAddReturnPass", Granularity::Function), pBuilder(builder) {} bool runOnFunction(Function *F, AnalysisManager& AM) override; + void getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const override; void *getPassID() const override { return &ID; } }; @@ -90,6 +94,7 @@ public: static void *ID; SysYCondBr2BrPass(IRBuilder *builder) : OptimizationPass("SysYCondBr2BrPass", Granularity::Function), pBuilder(builder) {} bool runOnFunction(Function *F, AnalysisManager& AM) override; + void getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const override; void *getPassID() const override { return &ID; } };