[SCCP]初步构建SCCP,.cpp仍不完善暂不commit
This commit is contained in:
196
src/include/SCCP.h
Normal file
196
src/include/SCCP.h
Normal file
@@ -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<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)
|
||||||
|
};
|
||||||
|
// LatticeValue: 用于表示值的状态,Top表示未知,Constant表示常量,Bottom表示未定义或变化的值。
|
||||||
|
// 这里的LatticeValue用于跟踪每个SSA值(变量、指令结果)的状态,
|
||||||
|
// 以便在SCCP过程中进行常量传播和控制流简化。
|
||||||
|
|
||||||
|
//TODO: 下列数据结构考虑集成到类中,避免重命名问题
|
||||||
|
static std::set<Instruction *> Worklist;
|
||||||
|
static std::unordered_set<BasicBlock*> Executable_Blocks;
|
||||||
|
static std::unordered_set<std::pair<BasicBlock *, BasicBlock *> > Executable_Edges;
|
||||||
|
static std::map<Value*, LatticeValue> 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<BasicBlock *, BasicBlock *> &edge);
|
||||||
|
void RemoveDeadBlock(BasicBlock *bb);
|
||||||
|
void UpdateState(Value *v, LatticeValue newState);
|
||||||
|
LatticeValue Meet(LatticeValue a, LatticeValue b);
|
||||||
|
LatticeValue GetValueState(Value *v);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace sysy
|
||||||
Reference in New Issue
Block a user