[midend]重构了src目录

This commit is contained in:
Lixuanwang
2025-07-29 21:30:30 +08:00
parent f5922d0178
commit 09ae47924e
84 changed files with 85 additions and 1715 deletions

View File

@@ -0,0 +1,160 @@
#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
#include <set> // For std::set
namespace sysy {
// 初始化静态 ID
void *LivenessAnalysisPass::ID = (void *)&LivenessAnalysisPass::ID;
// ==============================================================
// LivenessAnalysisResult 结果类的实现
// ==============================================================
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(); // 将持有在 BB 中定义的值
use.clear(); // 将持有在 BB 中使用但在其定义之前的值
// 临时集合,用于跟踪当前基本块中已经定义过的变量
std::set<Value *> defined_in_block_so_far;
// 按照指令在块中的顺序遍历
for (const auto &inst_ptr : BB->getInstructions()) {
Instruction *inst = inst_ptr.get();
// 1. 处理指令的操作数 (Use) - 在定义之前的使用
for (const auto &use_ptr : inst->getOperands()) { // 修正迭代器类型
Value *operand = use_ptr->getValue(); // 从 shared_ptr<Use> 获取 Value*
// 过滤掉常量和全局变量,因为它们通常不被视为活跃变量
ConstantValue *constValue = dynamic_cast<ConstantValue *>(operand);
GlobalValue *globalValue = dynamic_cast<GlobalValue *>(operand);
if (constValue || globalValue) {
continue; // 跳过常量和全局变量
}
// 如果操作数是一个变量Instruction 或 Argument并且它在此基本块的当前点之前尚未被定义
if (defined_in_block_so_far.find(operand) == defined_in_block_so_far.end()) {
use.insert(operand);
}
}
// 2. 处理指令自身产生的定义 (Def)
if (inst->isDefine()) { // 使用 isDefine() 方法
// 指令自身定义了一个值。将其添加到块的 def 集合,
// 并添加到当前块中已定义的值的临时集合。
def.insert(inst); // inst 本身就是被定义的值(例如,虚拟寄存器)
defined_in_block_so_far.insert(inst);
}
}
}
void LivenessAnalysisResult::computeLiveness(Function *F) {
// 每次计算前清空旧结果
liveInSets.clear(); // 直接清空 map不再使用 F 作为键
liveOutSets.clear(); // 直接清空 map
// 初始化所有基本块的 LiveIn 和 LiveOut 集合为空
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
liveInSets[bb] = {}; // 直接以 bb 为键
liveOutSets[bb] = {}; // 直接以 bb 为键
}
bool changed = true;
while (changed) {
changed = false;
// TODO : 目前为逆序遍历基本块,考虑反向拓扑序遍历基本块
// 逆序遍历基本块
// std::list<std::unique_ptr<BasicBlock>> basicBlocks(F->getBasicBlocks().begin(), F->getBasicBlocks().end());
// std::reverse(basicBlocks.begin(), basicBlocks.end());
// 然后遍历 basicBlocks
// 创建一个 BasicBlock* 的列表来存储指针,避免拷贝 unique_ptr
// Option 1: Using std::vector<BasicBlock*> (preferred for performance with reverse)
std::vector<BasicBlock*> basicBlocksPointers;
for (const auto& bb_ptr : F->getBasicBlocks()) {
basicBlocksPointers.push_back(bb_ptr.get());
}
std::reverse(basicBlocksPointers.begin(), basicBlocksPointers.end());
for (auto bb_iter = basicBlocksPointers.begin(); bb_iter != basicBlocksPointers.end(); ++bb_iter) {
BasicBlock *bb = *bb_iter; // 获取 BasicBlock 指针
if (!bb)
continue; // 避免空指针
std::set<Value *> oldLiveIn = liveInSets[bb];
std::set<Value *> oldLiveOut = liveOutSets[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[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[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 内部的方法来计算分析结果
CurrentLivenessResult->computeLiveness(F);
// 分析遍通常不修改 IR所以返回 false
return false;
}
std::unique_ptr<AnalysisResultBase> LivenessAnalysisPass::getResult() {
// 返回计算好的 LivenessAnalysisResult 实例,所有权转移给 AnalysisManager
return std::move(CurrentLivenessResult);
}
} // namespace sysy