diff --git a/src/include/SCCP.h b/src/include/SCCP.h new file mode 100644 index 0000000..da6452e --- /dev/null +++ b/src/include/SCCP.h @@ -0,0 +1,196 @@ +#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::unordered_set > 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