#pragma once #include "IR.h" 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 // 值->状态映射 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) }; // LatticeValue: 用于表示值的状态,Top表示未知,Constant表示常量,Bottom表示未定义或变化的值。 // 这里的LatticeValue用于跟踪每个SSA值(变量、指令结果)的状态, // 以便在SCCP过程中进行常量传播和控制流简化。 //TODO: 下列数据结构考虑集成到类中,避免重命名问题 static std::set Worklist; static std::unordered_set Executable_Blocks; static std::queue > Executable_Edges; static std::map valueState; class SCCP { private: Module *pModule; public: SCCP(Module *pMoudle) : pModule(pMoudle) {} void run(); bool PropagateConstants(Function *function); bool SimplifyControlFlow(Function *function); void ProcessInstruction(Instruction *inst); void ProcessEdge(const std::pair &edge); void RemoveDeadBlock(BasicBlock *bb); void UpdateState(Value *v, LatticeValue newState); LatticeValue Meet(LatticeValue a, LatticeValue b); LatticeValue GetValueState(Value *v); }; } // namespace sysy