[midend-SCCP]暂存1
This commit is contained in:
@@ -1,196 +1,149 @@
|
||||
#pragma once
|
||||
|
||||
#include "IR.h"
|
||||
#include "IR.h" // 假设这是你的 SysY IR 定义,包含 Value, Instruction, BasicBlock, Function, Module 等
|
||||
#include "Pass.h" // 包含 Pass 的基类定义,以及 AnalysisManager, IRBuilder
|
||||
#include "SysYIROptUtils.h" // 假设包含 SysYIROptUtils::usedelete 等辅助函数
|
||||
#include <cassert> // For assert
|
||||
#include <functional> // 引入 std::function 用于辅助函数
|
||||
#include <iostream> // For DEBUG output
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
#include <variant> // 引入 std::variant 用于 ConstVal
|
||||
|
||||
using ConstVal = std::variant<int, float>; // 定义一个变体类型,用于存储整数或浮点数常量
|
||||
|
||||
namespace sysy {
|
||||
|
||||
// 稀疏条件常量传播类
|
||||
// Sparse Conditional Constant Propagation
|
||||
/*
|
||||
伪代码
|
||||
function SCCP_Optimization(Module):
|
||||
for each Function in Module:
|
||||
changed = true
|
||||
while changed:
|
||||
changed = false
|
||||
// 阶段1: 常量传播与折叠
|
||||
changed |= PropagateConstants(Function)
|
||||
// 阶段2: 控制流简化
|
||||
changed |= SimplifyControlFlow(Function)
|
||||
end while
|
||||
end for
|
||||
|
||||
function PropagateConstants(Function):
|
||||
// 初始化
|
||||
executableBlocks = {entryBlock}
|
||||
valueState = map<Value, State> // 值->状态映射
|
||||
instWorkList = Queue()
|
||||
edgeWorkList = Queue()
|
||||
|
||||
// 初始化工作列表
|
||||
for each inst in entryBlock:
|
||||
instWorkList.push(inst)
|
||||
|
||||
// 迭代处理
|
||||
while !instWorkList.empty() || !edgeWorkList.empty():
|
||||
// 处理指令工作列表
|
||||
while !instWorkList.empty():
|
||||
inst = instWorkList.pop()
|
||||
// 如果指令是可执行基本块中的
|
||||
if executableBlocks.contains(inst.parent):
|
||||
ProcessInstruction(inst)
|
||||
|
||||
// 处理边工作列表
|
||||
while !edgeWorkList.empty():
|
||||
edge = edgeWorkList.pop()
|
||||
ProcessEdge(edge)
|
||||
|
||||
// 应用常量替换
|
||||
for each inst in Function:
|
||||
if valueState[inst] == CONSTANT:
|
||||
ReplaceWithConstant(inst, valueState[inst].constant)
|
||||
changed = true
|
||||
|
||||
return changed
|
||||
|
||||
function ProcessInstruction(Instruction inst):
|
||||
switch inst.type:
|
||||
//二元操作
|
||||
case BINARY_OP:
|
||||
lhs = GetValueState(inst.operands[0])
|
||||
rhs = GetValueState(inst.operands[1])
|
||||
if lhs == CONSTANT && rhs == CONSTANT:
|
||||
newState = ComputeConstant(inst.op, lhs.value, rhs.value)
|
||||
UpdateState(inst, newState)
|
||||
else if lhs == BOTTOM || rhs == BOTTOM:
|
||||
UpdateState(inst, BOTTOM)
|
||||
//phi
|
||||
case PHI:
|
||||
mergedState = ⊤
|
||||
for each incoming in inst.incomings:
|
||||
// 检查每个输入的状态
|
||||
if executableBlocks.contains(incoming.block):
|
||||
incomingState = GetValueState(incoming.value)
|
||||
mergedState = Meet(mergedState, incomingState)
|
||||
UpdateState(inst, mergedState)
|
||||
// 条件分支
|
||||
case COND_BRANCH:
|
||||
cond = GetValueState(inst.condition)
|
||||
if cond == CONSTANT:
|
||||
// 判断条件分支
|
||||
if cond.value == true:
|
||||
AddEdgeToWorkList(inst.parent, inst.trueTarget)
|
||||
else:
|
||||
AddEdgeToWorkList(inst.parent, inst.falseTarget)
|
||||
else if cond == BOTTOM:
|
||||
AddEdgeToWorkList(inst.parent, inst.trueTarget)
|
||||
AddEdgeToWorkList(inst.parent, inst.falseTarget)
|
||||
|
||||
case UNCOND_BRANCH:
|
||||
AddEdgeToWorkList(inst.parent, inst.target)
|
||||
|
||||
// 其他指令处理...
|
||||
|
||||
function ProcessEdge(Edge edge):
|
||||
fromBB, toBB = edge
|
||||
if !executableBlocks.contains(toBB):
|
||||
executableBlocks.add(toBB)
|
||||
for each inst in toBB:
|
||||
if inst is PHI:
|
||||
instWorkList.push(inst)
|
||||
else:
|
||||
instWorkList.push(inst) // 非PHI指令
|
||||
|
||||
// 更新PHI节点的输入
|
||||
for each phi in toBB.phis:
|
||||
instWorkList.push(phi)
|
||||
|
||||
function SimplifyControlFlow(Function):
|
||||
changed = false
|
||||
// 标记可达基本块
|
||||
ReachableBBs = FindReachableBlocks(Function.entry)
|
||||
|
||||
// 删除不可达块
|
||||
for each bb in Function.blocks:
|
||||
if !ReachableBBs.contains(bb):
|
||||
RemoveDeadBlock(bb)
|
||||
changed = true
|
||||
|
||||
// 简化条件分支
|
||||
for each bb in Function.blocks:
|
||||
terminator = bb.terminator
|
||||
if terminator is COND_BRANCH:
|
||||
cond = GetValueState(terminator.condition)
|
||||
if cond == CONSTANT:
|
||||
SimplifyBranch(terminator, cond.value)
|
||||
changed = true
|
||||
|
||||
return changed
|
||||
|
||||
function RemoveDeadBlock(BasicBlock bb):
|
||||
// 1. 更新前驱块的分支指令
|
||||
for each pred in bb.predecessors:
|
||||
UpdateTerminator(pred, bb)
|
||||
|
||||
// 2. 更新后继块的PHI节点
|
||||
for each succ in bb.successors:
|
||||
RemovePhiIncoming(succ, bb)
|
||||
|
||||
// 3. 删除块内所有指令
|
||||
for each inst in bb.instructions:
|
||||
inst.remove()
|
||||
|
||||
// 4. 从函数中移除基本块
|
||||
Function.removeBlock(bb)
|
||||
|
||||
function Meet(State a, State b):
|
||||
if a == ⊤: return b
|
||||
if b == ⊤: return a
|
||||
if a == ⊥ || b == ⊥: return ⊥
|
||||
if a.value == b.value: return a
|
||||
return ⊥
|
||||
|
||||
function UpdateState(Value v, State newState):
|
||||
oldState = valueState.get(v, ⊤)
|
||||
if newState != oldState:
|
||||
valueState[v] = newState
|
||||
for each user in v.users:
|
||||
if user is Instruction:
|
||||
instWorkList.push(user)
|
||||
|
||||
*/
|
||||
|
||||
enum class LatticeValue {
|
||||
Top, // ⊤ (Unknown)
|
||||
Constant, // c (Constant)
|
||||
Bottom // ⊥ (Undefined / Varying)
|
||||
// 定义三值格 (Three-valued Lattice) 的状态
|
||||
enum class LatticeVal {
|
||||
Top, // ⊤ (未知 / 未初始化)
|
||||
Constant, // c (常量)
|
||||
Bottom// ⊥ (不确定 / 变化 / 未定义)
|
||||
};
|
||||
// LatticeValue: 用于表示值的状态,Top表示未知,Constant表示常量,Bottom表示未定义或变化的值。
|
||||
// 这里的LatticeValue用于跟踪每个SSA值(变量、指令结果)的状态,
|
||||
// 以便在SCCP过程中进行常量传播和控制流简化。
|
||||
|
||||
//TODO: 下列数据结构考虑集成到类中,避免重命名问题
|
||||
static std::set<Instruction *> Worklist;
|
||||
static std::unordered_set<BasicBlock*> Executable_Blocks;
|
||||
static std::queue<std::pair<BasicBlock *, BasicBlock *> > Executable_Edges;
|
||||
static std::map<Value*, LatticeValue> valueState;
|
||||
// 用于表示 SSA 值的具体状态(包含格值和常量值)
|
||||
// 新增枚举来区分常量的实际类型
|
||||
enum class ValueType {
|
||||
Integer,
|
||||
Float,
|
||||
Unknown // 用于 Top 和 Bottom 状态
|
||||
};
|
||||
|
||||
class SCCP {
|
||||
struct SSAPValue {
|
||||
LatticeVal state;
|
||||
ConstVal constantVal; // 使用 std::variant 存储 int 或 float
|
||||
ValueType constant_type; // 记录常量是整数还是浮点数
|
||||
|
||||
// 默认构造函数,初始化为 Top
|
||||
SSAPValue() : state(LatticeVal::Top), constantVal(0), constant_type(ValueType::Unknown) {}
|
||||
// 构造函数,用于创建 Bottom 状态
|
||||
SSAPValue(LatticeVal s) : state(s), constantVal(0), constant_type(ValueType::Unknown) {
|
||||
assert((s == LatticeVal::Top || s == LatticeVal::Bottom) && "SSAPValue(LatticeVal) only for Top/Bottom");
|
||||
}
|
||||
// 构造函数,用于创建 int Constant 状态
|
||||
SSAPValue(int c) : state(LatticeVal::Constant), constantVal(c), constant_type(ValueType::Integer) {}
|
||||
// 构造函数,用于创建 float Constant 状态
|
||||
SSAPValue(float c) : state(LatticeVal::Constant), constantVal(c), constant_type(ValueType::Float) {}
|
||||
|
||||
// 比较操作符,用于判断状态是否改变
|
||||
bool operator==(const SSAPValue &other) const {
|
||||
if (state != other.state)
|
||||
return false;
|
||||
if (state == LatticeVal::Constant) {
|
||||
if (constant_type != other.constant_type)
|
||||
return false; // 类型必须匹配
|
||||
return constantVal == other.constantVal; // std::variant 会比较内部值
|
||||
}
|
||||
return true; // Top == Top, Bottom == Bottom
|
||||
}
|
||||
bool operator!=(const SSAPValue &other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
// SCCP 上下文类,持有每个函数运行时的状态
|
||||
class SCCPContext {
|
||||
private:
|
||||
Module *pModule;
|
||||
IRBuilder *builder; // IR 构建器,用于插入指令和创建常量
|
||||
|
||||
// 工作列表
|
||||
// 存储需要重新评估的指令
|
||||
std::queue<Instruction *> instWorkList;
|
||||
// 存储需要重新评估的控制流边 (pair: from_block, to_block)
|
||||
std::queue<std::pair<BasicBlock *, BasicBlock *>> edgeWorkList;
|
||||
|
||||
// 格值映射:SSA Value 到其当前状态
|
||||
std::map<Value *, SSAPValue> valueState;
|
||||
// 可执行基本块集合
|
||||
std::unordered_set<BasicBlock *> executableBlocks;
|
||||
// 追踪已访问的CFG边,防止重复添加
|
||||
std::unordered_set<std::pair<BasicBlock *, BasicBlock *>, SysYIROptUtils::PairHash> visitedCFGEdges;
|
||||
|
||||
// 辅助函数:格操作 Meet
|
||||
SSAPValue Meet(const SSAPValue &a, const SSAPValue &b);
|
||||
// 辅助函数:获取值的当前状态,如果不存在则默认为 Top
|
||||
SSAPValue GetValueState(Value *v);
|
||||
// 辅助函数:更新值的状态,如果状态改变,将所有用户加入指令工作列表
|
||||
void UpdateState(Value *v, SSAPValue newState);
|
||||
// 辅助函数:将边加入边工作列表,并更新可执行块
|
||||
void AddEdgeToWorkList(BasicBlock *fromBB, BasicBlock *toBB);
|
||||
// 辅助函数:标记一个块为可执行
|
||||
void MarkBlockExecutable(BasicBlock *block);
|
||||
|
||||
// 辅助函数:对二元操作进行常量折叠
|
||||
SSAPValue ComputeConstant(BinaryInst *binaryinst, SSAPValue lhsVal, SSAPValue rhsVal);
|
||||
// 辅助函数:对一元操作进行常量折叠
|
||||
SSAPValue ComputeConstant(UnaryInst *unaryInst, SSAPValue operandVal);
|
||||
// 辅助函数:对类型转换进行常量折叠
|
||||
SSAPValue ComputeConstant(CastInst *castInst, SSAPValue operandVal);
|
||||
|
||||
// 主要优化阶段
|
||||
// 阶段1: 常量传播与折叠
|
||||
// 返回值表示在此阶段IR是否被修改
|
||||
bool PropagateConstants(Function *func);
|
||||
// 阶段2: 控制流简化
|
||||
// 返回值表示在此阶段IR是否被修改
|
||||
bool SimplifyControlFlow(Function *func);
|
||||
|
||||
// 辅助函数:处理单条指令(这包含了原来 computeLatticeValue 的大部分逻辑)
|
||||
void ProcessInstruction(Instruction *inst);
|
||||
// 辅助函数:处理单条控制流边
|
||||
void ProcessEdge(const std::pair<BasicBlock *, BasicBlock *> &edge);
|
||||
|
||||
// 控制流简化辅助函数
|
||||
// 查找所有可达的基本块 (基于常量条件)
|
||||
std::unordered_set<BasicBlock *> FindReachableBlocks(Function *func);
|
||||
// 移除死块
|
||||
void RemoveDeadBlock(BasicBlock *bb, Function *func);
|
||||
// 简化分支(将条件分支替换为无条件分支)
|
||||
void SimplifyBranch(BranchInst *brInst, bool condVal); // 修改为 BranchInst,更通用
|
||||
// 更新前驱块的终结指令(当一个后继块被移除时)
|
||||
void UpdateTerminator(BasicBlock *predBB, BasicBlock *removedSucc);
|
||||
// 移除 Phi 节点的入边(当其前驱块被移除时)
|
||||
void RemovePhiIncoming(BasicBlock *phiParentBB, BasicBlock *removedPred);
|
||||
|
||||
public:
|
||||
SCCP(Module *pMoudle) : pModule(pMoudle) {}
|
||||
SCCPContext(IRBuilder *builder) : builder(builder) {}
|
||||
|
||||
void run();
|
||||
bool PropagateConstants(Function *function);
|
||||
bool SimplifyControlFlow(Function *function);
|
||||
void ProcessInstruction(Instruction *inst);
|
||||
void ProcessEdge(const std::pair<BasicBlock *, BasicBlock *> &edge);
|
||||
void RemoveDeadBlock(BasicBlock *bb);
|
||||
void UpdateState(Value *v, LatticeValue newState);
|
||||
LatticeValue Meet(LatticeValue a, LatticeValue b);
|
||||
LatticeValue GetValueState(Value *v);
|
||||
// 运行 SCCP 优化
|
||||
// func: 当前要优化的函数
|
||||
// AM: 分析管理器,在 SCCP 中通常不需要获取其他分析结果,但可能需要使分析结果失效。
|
||||
// 返回值: 如果对函数进行了修改,则为 true
|
||||
void run(Function *func, AnalysisManager &AM);
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
// SCCP 优化遍类,继承自 OptimizationPass
|
||||
class SCCP : public OptimizationPass {
|
||||
private:
|
||||
IRBuilder *builder; // IR 构建器,作为 Pass 的成员,传入 Context
|
||||
|
||||
public:
|
||||
SCCP(IRBuilder *builder) : OptimizationPass("SCCP", Granularity::Function), builder(builder) {}
|
||||
static void *ID;
|
||||
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; }
|
||||
};
|
||||
|
||||
} // namespace sysy
|
||||
Reference in New Issue
Block a user