[miden]DCE引入ctx避免重复运行遍导致的状态污染。修复天然活跃判断条件
This commit is contained in:
@@ -1,46 +1,63 @@
|
||||
#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> // 用于存储活跃指令
|
||||
#include "Pass.h"
|
||||
#include "IR.h"
|
||||
#include "SysYIROptUtils.h"
|
||||
#include "Dom.h"
|
||||
#include <unordered_set>
|
||||
#include <queue>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
// 前向声明分析结果类,确保在需要时可以引用
|
||||
// class DominatorTreeAnalysisResult; // Pass.h 中已包含,这里不再需要
|
||||
class SideEffectInfoAnalysisResult; // 假设有副作用分析结果类
|
||||
|
||||
// DCEContext 类,用于封装DCE的内部逻辑和状态
|
||||
// 这样可以避免静态变量在多线程或多次运行时的冲突,并保持代码的模块化
|
||||
class DCEContext {
|
||||
public:
|
||||
// 运行DCE的主要方法
|
||||
// func: 当前要优化的函数
|
||||
// tp: 分析管理器,用于获取其他分析结果(如果需要)
|
||||
void run(Function* func, AnalysisManager* AM, bool &changed);
|
||||
|
||||
private:
|
||||
// 存储活跃指令的集合
|
||||
std::unordered_set<Instruction*> alive_insts;
|
||||
|
||||
// 判断指令是否是“天然活跃”的(即总是保留的)
|
||||
// inst: 要检查的指令
|
||||
// 返回值: 如果指令是天然活跃的,则为true,否则为false
|
||||
bool isAlive(Instruction* inst);
|
||||
|
||||
// 递归地将活跃指令及其依赖加入到 alive_insts 集合中
|
||||
// inst: 要标记为活跃的指令
|
||||
void addAlive(Instruction* inst);
|
||||
};
|
||||
|
||||
// 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() : OptimizationPass("DCE", Granularity::Function) {}
|
||||
|
||||
// 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; }
|
||||
// 静态成员,作为该遍的唯一ID
|
||||
static void *ID;
|
||||
|
||||
// 运行在函数上的优化逻辑
|
||||
// F: 当前要优化的函数
|
||||
// AM: 分析管理器,用于获取或使分析结果失效
|
||||
// 返回值: 如果IR被修改,则为true,否则为false
|
||||
bool runOnFunction(Function *F, AnalysisManager& AM) override;
|
||||
|
||||
// 声明该遍的分析依赖和失效信息
|
||||
// analysisDependencies: 该遍运行前需要哪些分析结果
|
||||
// analysisInvalidations: 该遍运行后会使哪些分析结果失效
|
||||
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override;
|
||||
|
||||
// Pass 基类中的纯虚函数,必须实现
|
||||
void *getPassID() const override { return &ID; }
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
Reference in New Issue
Block a user