diff --git a/src/CFGOptPass.cpp b/src/CFGOptPass.cpp new file mode 100644 index 0000000..224a553 --- /dev/null +++ b/src/CFGOptPass.cpp @@ -0,0 +1,706 @@ +#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/Liveness.cpp b/src/Liveness.cpp new file mode 100644 index 0000000..8b92b3d --- /dev/null +++ b/src/Liveness.cpp @@ -0,0 +1,145 @@ +#include "Liveness.h" +#include // For std::set_union, std::set_difference +#include +#include // Potentially for worklist, though not strictly needed for the iterative approach below + +namespace sysy { + +// 初始化静态 ID +char LivenessAnalysisPass::ID = 0; // 任何唯一的地址都可以,这里用 0 + +// ============================================================== +// LivenessAnalysisResult 结果类的实现 +// ============================================================== + +LivenessAnalysisResult::LivenessAnalysisResult(Function *F) : AssociatedFunction(F) { + // 构造时可以不计算,在分析遍运行里计算并填充 +} + +const std::set *LivenessAnalysisResult::getLiveIn(BasicBlock *BB) const { + auto it = liveInSets.find(BB); + if (it != liveInSets.end()) { + return &(it->second); + } + // 返回一个空集合,表示未找到或不存在 + static const std::set emptySet; + return &emptySet; +} + +const std::set *LivenessAnalysisResult::getLiveOut(BasicBlock *BB) const { + auto it = liveOutSets.find(BB); + if (it != liveOutSets.end()) { + return &(it->second); + } + static const std::set emptySet; + return &emptySet; +} + +void LivenessAnalysisResult::computeDefUse(BasicBlock *BB, std::set &def, std::set &use) { + def.clear(); + use.clear(); + + // 按照指令在块中的顺序遍历 + for (const auto &inst_ptr : BB->getInstructions()) { + Instruction *inst = inst_ptr.get(); + + // 检查指令是否产生值 (Def) + if (inst->hasValue()) { // 假设 Instruction 有 hasValue() 方法判断是否生成结果值 + // 如果这个值在此指令之前在块中被使用过,则它是一个 Use + // 否则,它是 Def + if (use.find(inst) == use.end()) { // 如果当前指令本身的值未被当前块内之前的指令使用 + def.insert(inst); + } + } + + // 检查指令的操作数 (Use) + for (Value *operand : inst->getOperands()) { // 假设 Instruction 有 getOperands() 返回 Value* + // 只有当操作数是一个Instruction或Argument且未在当前块中被定义时,才算作 Use + if (auto opInst = dynamic_cast(operand)) { + if (def.find(opInst) == def.end()) { // 如果操作数不是由当前块中之前的指令定义 + use.insert(opInst); + } + } else if (auto arg = dynamic_cast(operand)) { + use.insert(arg); + } + // 常量和全局变量不计入 Def/Use 集合,因为它们不随控制流变化 + } + } +} + +void LivenessAnalysisResult::computeLiveness(Function *F) { + // 每次计算前清空旧结果 + liveInSets[F].clear(); + liveOutSets[F].clear(); + + // 初始化所有基本块的 LiveIn 和 LiveOut 集合为空 + for (const auto &bb_ptr : F->getBasicBlocks()) { + BasicBlock *bb = bb_ptr.get(); + liveInSets[F][bb] = {}; + liveOutSets[F][bb] = {}; + } + + bool changed = true; + while (changed) { + changed = false; + + // 迭代所有基本块,通常逆序遍历(reverse post-order)可以加快收敛, + // 但为了简化,这里直接遍历所有块。 + for (const auto &bb_ptr : F->getBasicBlocks()) { + BasicBlock *bb = bb_ptr.get(); + + std::set oldLiveIn = liveInSets[F][bb]; + std::set oldLiveOut = liveOutSets[F][bb]; + + // 1. 计算 LiveOut(BB) = Union(LiveIn(Succ) for Succ in Successors(BB)) + std::set newLiveOut; + for (BasicBlock *succ : bb->getSuccessors()) { + const std::set *succLiveIn = getLiveIn(succ); // 递归获取后继的 LiveIn + if (succLiveIn) { + newLiveOut.insert(succLiveIn->begin(), succLiveIn->end()); + } + } + liveOutSets[F][bb] = newLiveOut; + + // 2. 计算 LiveIn(BB) = Use(BB) Union (LiveOut(BB) - Def(BB)) + std::set defSet, useSet; + computeDefUse(bb, defSet, useSet); // 计算当前块的 Def 和 Use + + std::set liveOutMinusDef; + std::set_difference(newLiveOut.begin(), newLiveOut.end(), defSet.begin(), defSet.end(), + std::inserter(liveOutMinusDef, liveOutMinusDef.begin())); + + std::set newLiveIn = useSet; + newLiveIn.insert(liveOutMinusDef.begin(), liveOutMinusDef.end()); + liveInSets[F][bb] = newLiveIn; + + // 检查是否发生变化 + if (oldLiveIn != newLiveIn || oldLiveOut != newLiveOut) { + changed = true; + } + } + } +} + +// ============================================================== +// LivenessAnalysisPass 的实现 +// ============================================================== + +bool LivenessAnalysisPass::runOnFunction(Function *F, AnalysisManager &AM) { + // 每次运行创建一个新的 LivenessAnalysisResult 对象来存储结果 + CurrentLivenessResult = std::make_unique(F); + + // 调用 LivenessAnalysisResult 内部的方法来计算分析结果 + // 这里的 computeLiveness 不需要 AM 参数,因为它自身不依赖其他分析。 + CurrentLivenessResult->computeLiveness(F); + + // 分析遍通常不修改 IR,所以返回 false + return false; +} + +std::unique_ptr LivenessAnalysisPass::getResult() { + // 返回计算好的 LivenessAnalysisResult 实例,所有权转移给 AnalysisManager + return std::move(CurrentLivenessResult); +} + +} // namespace sysy \ No newline at end of file diff --git a/src/include/CFGOptPass.h b/src/include/CFGOptPass.h new file mode 100644 index 0000000..d4c4f8e --- /dev/null +++ b/src/include/CFGOptPass.h @@ -0,0 +1,40 @@ +#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/Liveness.h b/src/include/Liveness.h new file mode 100644 index 0000000..d804d33 --- /dev/null +++ b/src/include/Liveness.h @@ -0,0 +1,72 @@ +#pragma once + +#include "IR.h" // 包含 IR 定义 +#include "Pass.h" // 包含 Pass 框架 +#include // for std::set_union, std::set_difference +#include +#include +#include + +namespace sysy { + +// 前向声明 +class Function; +class BasicBlock; +class Value; +class Instruction; + +// 活跃变量分析结果类 +// 它将包含 LiveIn 和 LiveOut 集合 +class LivenessAnalysisResult : public AnalysisResultBase { +public: + LivenessAnalysisResult(Function *F); // 构造函数,需要一个函数来关联结果 + + // 获取给定基本块的 LiveIn 集合 + const std::set *getLiveIn(BasicBlock *BB) const; + + // 获取给定基本块的 LiveOut 集合 + const std::set *getLiveOut(BasicBlock *BB) const; + + // 暴露内部数据结构,如果需要更直接的访问 + const std::map> &getLiveInSets() const { return liveInSets; } + const std::map> &getLiveOutSets() const { return liveOutSets; } + + // 核心计算方法,由 LivenessAnalysisPass 调用 + void computeLiveness(Function *F); + +private: + Function *AssociatedFunction; // 这个活跃变量分析是为哪个函数计算的 + std::map> liveInSets; + std::map> liveOutSets; + + // 辅助函数:计算基本块的 Def 和 Use 集合 + // Def: 块内定义,且定义在所有使用之前的值 + // Use: 块内使用,且使用在所有定义之前的值 + void computeDefUse(BasicBlock *BB, std::set &def, std::set &use); +}; + +// 活跃变量分析遍 +class LivenessAnalysisPass : public AnalysisPass { +public: + // 唯一的 Pass ID + static char ID; // LLVM 风格的唯一 ID + + LivenessAnalysisPass() : AnalysisPass("LivenessAnalysis", Pass::Granularity::Function) {} + + // 实现 getPassID + void *getPassID() const override { return &ID; } + + // 运行分析并返回结果。现在接受 AnalysisManager& AM 参数 + bool runOnFunction(Function *F, AnalysisManager &AM) override; + + // 获取分析结果的指针。 + // 注意:AnalysisManager 将会调用此方法来获取结果并进行缓存。 + std::unique_ptr getResult() override; + +private: + // 存储当前分析计算出的 LivenessAnalysisResult 实例 + // runOnFunction 每次调用都会创建新的 LivenessAnalysisResult 对象 + std::unique_ptr CurrentLivenessResult; +}; + +} // namespace sysy \ No newline at end of file