[midend]部分DCE遍实现(传播活跃代码),修改优化遍运行逻辑,TODO:完善优化遍的getAnalysisUsage,删除无用代码
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
# 记录中端遍的唯一标识ID
|
||||
# 记录中端遍的开发进度
|
||||
|
||||
| 名称 | 优化级别 | 开发进度 |
|
||||
| ------------ | ------------ | ---------- |
|
||||
| CFG优化 | 函数级 | 已完成 |
|
||||
| DCE | 函数级 | 待测试 |
|
||||
@ -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 <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
|
||||
@ -25,7 +25,7 @@ add_executable(sysyc
|
||||
Pass.cpp
|
||||
Dom.cpp
|
||||
Liveness.cpp
|
||||
# DeadCodeElimination.cpp
|
||||
DCE.cpp
|
||||
AddressCalculationExpansion.cpp
|
||||
# Mem2Reg.cpp
|
||||
# Reg2Mem.cpp
|
||||
|
||||
91
src/DCE.cpp
Normal file
91
src/DCE.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
#include "DCE.h"
|
||||
#include "IR.h"
|
||||
#include "SysYIROptUtils.h"
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
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<ir::CallInst>(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<Instruction *>(operand->getValue())) {
|
||||
addAlive(opInst); // 递归地将操作数指令标记为活跃
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sysy
|
||||
48
src/Pass.cpp
48
src/Pass.cpp
@ -2,6 +2,7 @@
|
||||
#include "Liveness.h"
|
||||
#include "SysYIRCFGOpt.h"
|
||||
#include "SysYIRPrinter.h"
|
||||
#include "DCE.h"
|
||||
#include "Pass.h"
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
@ -44,39 +45,30 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
||||
registerOptimizationPass<SysYAddReturnPass>(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();
|
||||
|
||||
@ -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();) {
|
||||
|
||||
@ -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<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
|
||||
46
src/include/DCE.h
Normal file
46
src/include/DCE.h
Normal file
@ -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 <unordered_set> // 用于存储活跃指令
|
||||
|
||||
namespace sysy {
|
||||
|
||||
// DCE 优化遍类,继承自 OptimizationPass
|
||||
class DCE : public OptimizationPass {
|
||||
private:
|
||||
std::unordered_set<Instruction *> 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<void *> &analysisDependencies, std::set<void *> &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
|
||||
@ -291,6 +291,7 @@ public:
|
||||
|
||||
AnalysisManager &getAnalysisManager() { return analysisManager; }
|
||||
|
||||
void clearPasses();
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
@ -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<void *> &analysisDependencies, std::set<void *> &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<void *> &analysisDependencies, std::set<void *> &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<void *> &analysisDependencies, std::set<void *> &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<void *> &analysisDependencies, std::set<void *> &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<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override;
|
||||
void *getPassID() const override { return &ID; }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user