[midend]活跃变量分析,CFG优化遍重写。还未跑通,暂存

This commit is contained in:
rain2133
2025-07-21 15:20:46 +08:00
parent 550f4017be
commit a72fc541fb
4 changed files with 963 additions and 0 deletions

706
src/CFGOptPass.cpp Normal file
View File

@ -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 <cassert>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <queue> // For SysYDelNoPreBLock
#include <string>
namespace sysy {
char CFGOptimizationPass::ID = 0; // 初始化静态 ID
// 声明分析依赖和失效
void CFGOptimizationPass::getAnalysisUsage(std::set<void *> &analysisDependencies,
std::set<void *> &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<BasicBlock *> 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<BasicBlock *>(currentTerminator->getOperand(0));
if (branchBlock) {
basicBlock->addSuccessor(branchBlock);
branchBlock->addPredecessor(basicBlock.get());
}
} else if (currentTerminator->isConditional()) {
BasicBlock *thenBlock = dynamic_cast<BasicBlock *>(currentTerminator->getOperand(1));
BasicBlock *elseBlock = dynamic_cast<BasicBlock *>(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<PhiInst *>(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<BasicBlock *> 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<BasicBlock *> 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<BasicBlock *> 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 *>(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<BasicBlock *, BasicBlock *> 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<BasicBlock *>(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<BasicBlock *>(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<PhiInst *>(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<BasicBlock *>((*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<PhiInst *>(InstInNew_ptr.get());
if (phi) {
// 使用 replaceold2new 替换 phi 传入的基本块
phi->replaceold2new(oldTargetBlock, basicBlock);
}
} else {
break;
}
}
}
} else if ((*lastInst)->isConditional()) {
BasicBlock *oldThenBlock = dynamic_cast<BasicBlock *>((*lastInst)->getOperand(1));
BasicBlock *oldElseBlock = dynamic_cast<BasicBlock *>((*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<PhiInst *>(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<PhiInst *>(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<BasicBlock *> 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<ConstantValue *>(condOperand);
if (constOperand != nullptr) { // 条件操作数是常量
changed = true;
BasicBlock *thenBlock = dynamic_cast<BasicBlock *>((*lastInstIter)->getOperand(1));
BasicBlock *elseBlock = dynamic_cast<BasicBlock *>((*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 *>(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

145
src/Liveness.cpp Normal file
View File

@ -0,0 +1,145 @@
#include "Liveness.h"
#include <algorithm> // For std::set_union, std::set_difference
#include <iostream>
#include <queue> // 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<Value *> *LivenessAnalysisResult::getLiveIn(BasicBlock *BB) const {
auto it = liveInSets.find(BB);
if (it != liveInSets.end()) {
return &(it->second);
}
// 返回一个空集合,表示未找到或不存在
static const std::set<Value *> emptySet;
return &emptySet;
}
const std::set<Value *> *LivenessAnalysisResult::getLiveOut(BasicBlock *BB) const {
auto it = liveOutSets.find(BB);
if (it != liveOutSets.end()) {
return &(it->second);
}
static const std::set<Value *> emptySet;
return &emptySet;
}
void LivenessAnalysisResult::computeDefUse(BasicBlock *BB, std::set<Value *> &def, std::set<Value *> &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<Instruction *>(operand)) {
if (def.find(opInst) == def.end()) { // 如果操作数不是由当前块中之前的指令定义
use.insert(opInst);
}
} else if (auto arg = dynamic_cast<Argument *>(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<Value *> oldLiveIn = liveInSets[F][bb];
std::set<Value *> oldLiveOut = liveOutSets[F][bb];
// 1. 计算 LiveOut(BB) = Union(LiveIn(Succ) for Succ in Successors(BB))
std::set<Value *> newLiveOut;
for (BasicBlock *succ : bb->getSuccessors()) {
const std::set<Value *> *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<Value *> defSet, useSet;
computeDefUse(bb, defSet, useSet); // 计算当前块的 Def 和 Use
std::set<Value *> liveOutMinusDef;
std::set_difference(newLiveOut.begin(), newLiveOut.end(), defSet.begin(), defSet.end(),
std::inserter(liveOutMinusDef, liveOutMinusDef.begin()));
std::set<Value *> 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<LivenessAnalysisResult>(F);
// 调用 LivenessAnalysisResult 内部的方法来计算分析结果
// 这里的 computeLiveness 不需要 AM 参数,因为它自身不依赖其他分析。
CurrentLivenessResult->computeLiveness(F);
// 分析遍通常不修改 IR所以返回 false
return false;
}
std::unique_ptr<AnalysisResultBase> LivenessAnalysisPass::getResult() {
// 返回计算好的 LivenessAnalysisResult 实例,所有权转移给 AnalysisManager
return std::move(CurrentLivenessResult);
}
} // namespace sysy

40
src/include/CFGOptPass.h Normal file
View File

@ -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<void*>& analysisDependencies, std::set<void*>& 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

72
src/include/Liveness.h Normal file
View File

@ -0,0 +1,72 @@
#pragma once
#include "IR.h" // 包含 IR 定义
#include "Pass.h" // 包含 Pass 框架
#include <algorithm> // for std::set_union, std::set_difference
#include <map>
#include <set>
#include <vector>
namespace sysy {
// 前向声明
class Function;
class BasicBlock;
class Value;
class Instruction;
// 活跃变量分析结果类
// 它将包含 LiveIn 和 LiveOut 集合
class LivenessAnalysisResult : public AnalysisResultBase {
public:
LivenessAnalysisResult(Function *F); // 构造函数,需要一个函数来关联结果
// 获取给定基本块的 LiveIn 集合
const std::set<Value *> *getLiveIn(BasicBlock *BB) const;
// 获取给定基本块的 LiveOut 集合
const std::set<Value *> *getLiveOut(BasicBlock *BB) const;
// 暴露内部数据结构,如果需要更直接的访问
const std::map<BasicBlock *, std::set<Value *>> &getLiveInSets() const { return liveInSets; }
const std::map<BasicBlock *, std::set<Value *>> &getLiveOutSets() const { return liveOutSets; }
// 核心计算方法,由 LivenessAnalysisPass 调用
void computeLiveness(Function *F);
private:
Function *AssociatedFunction; // 这个活跃变量分析是为哪个函数计算的
std::map<BasicBlock *, std::set<Value *>> liveInSets;
std::map<BasicBlock *, std::set<Value *>> liveOutSets;
// 辅助函数:计算基本块的 Def 和 Use 集合
// Def: 块内定义,且定义在所有使用之前的值
// Use: 块内使用,且使用在所有定义之前的值
void computeDefUse(BasicBlock *BB, std::set<Value *> &def, std::set<Value *> &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<AnalysisResultBase> getResult() override;
private:
// 存储当前分析计算出的 LivenessAnalysisResult 实例
// runOnFunction 每次调用都会创建新的 LivenessAnalysisResult 对象
std::unique_ptr<LivenessAnalysisResult> CurrentLivenessResult;
};
} // namespace sysy