diff --git a/src/midend/Pass/Optimize/SCCP.cpp b/src/midend/Pass/Optimize/SCCP.cpp index e83bc31..e8ef384 100644 --- a/src/midend/Pass/Optimize/SCCP.cpp +++ b/src/midend/Pass/Optimize/SCCP.cpp @@ -280,6 +280,22 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { return; // 不处理不可达块中的指令的实际值 } + if(DEBUG) { + std::cout << "Processing instruction: " << inst->getName() << " in block " << inst->getParent()->getName() << std::endl; + std::cout << "Old state: "; + if (oldState.state == LatticeVal::Top) { + std::cout << "Top"; + } else if (oldState.state == LatticeVal::Constant) { + if (oldState.constant_type == ValueType::Integer) { + std::cout << "Const(" << std::get(oldState.constantVal) << ")"; + } else { + std::cout << "Const(" << std::get(oldState.constantVal) << ")"; + } + } else { + std::cout << "Bottom"; + } + } + switch (inst->getKind()) { case Instruction::kAdd: case Instruction::kSub: @@ -398,6 +414,7 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { newState = SSAPValue(); // 保持 Top break; case Instruction::kCall: + // TODO: 处理 Call 指令根据副作用分析可以推断的常量 // 大多数 Call 指令都假定为 Bottom,除非是纯函数且所有参数都是常量 newState = SSAPValue(LatticeVal::Bottom); break; @@ -417,19 +434,71 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { } case Instruction::kPhi: { PhiInst *phi = static_cast(inst); + if(DEBUG) { + std::cout << "Processing Phi node: " << phi->getName() << std::endl; + } + // 标准SCCP的phi节点处理: + // 只考虑可执行前驱,但要保证单调性 + SSAPValue currentPhiState = GetValueState(phi); SSAPValue phiResult = SSAPValue(); // 初始为 Top - + bool hasAnyExecutablePred = false; + for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) { - Value *incomingVal = phi->getIncomingValue(i); BasicBlock *incomingBlock = phi->getIncomingBlock(i); - - if (executableBlocks.count(incomingBlock)) { // 仅考虑可执行前驱 - phiResult = Meet(phiResult, GetValueState(incomingVal)); - if (phiResult.state == LatticeVal::Bottom) - break; // 如果已经 Bottom,则提前退出 + + if (executableBlocks.count(incomingBlock)) { + hasAnyExecutablePred = true; + Value *incomingVal = phi->getIncomingValue(i); + SSAPValue incomingState = GetValueState(incomingVal); + if(DEBUG) { + std::cout << " Incoming from block " << incomingBlock->getName() + << " with value " << incomingVal->getName() << " state: "; + if (incomingState.state == LatticeVal::Top) + std::cout << "Top"; + else if (incomingState.state == LatticeVal::Constant) { + if (incomingState.constant_type == ValueType::Integer) + std::cout << "Const(" << std::get(incomingState.constantVal) << ")"; + else + std::cout << "Const(" << std::get(incomingState.constantVal) << ")"; + } else + std::cout << "Bottom"; + std::cout << std::endl; + } + phiResult = Meet(phiResult, incomingState); + + if (phiResult.state == LatticeVal::Bottom) { + break; // 提前退出优化 + } + } + // 不可执行前驱暂时被忽略 + // 这是标准SCCP的做法,依赖于单调性保证正确性 + } + + if (!hasAnyExecutablePred) { + // 没有可执行前驱,保持Top状态 + newState = SSAPValue(); + } else { + // 关键修复:使用严格的单调性 + // 确保phi的值只能从Top -> Constant -> Bottom单向变化 + if (currentPhiState.state == LatticeVal::Top) { + // 从Top状态,可以变为任何计算结果 + newState = phiResult; + } else if (currentPhiState.state == LatticeVal::Constant) { + // 从Constant状态,只能保持相同常量或变为Bottom + if (phiResult.state == LatticeVal::Constant && + currentPhiState.constantVal == phiResult.constantVal && + currentPhiState.constant_type == phiResult.constant_type) { + // 保持相同的常量 + newState = currentPhiState; + } else { + // 不同的值,必须变为Bottom + newState = SSAPValue(LatticeVal::Bottom); + } + } else { + // 已经是Bottom,保持Bottom + newState = currentPhiState; } } - newState = phiResult; break; } case Instruction::kAlloca: // 对应 kAlloca @@ -486,6 +555,22 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { } } } + + if (DEBUG) { + std::cout << "New state: "; + if (newState.state == LatticeVal::Top) { + std::cout << "Top"; + } else if (newState.state == LatticeVal::Constant) { + if (newState.constant_type == ValueType::Integer) { + std::cout << "Const(" << std::get(newState.constantVal) << ")"; + } else { + std::cout << "Const(" << std::get(newState.constantVal) << ")"; + } + } else { + std::cout << "Bottom"; + } + std::cout << std::endl; + } } // 辅助函数:处理单条控制流边 @@ -493,14 +578,22 @@ void SCCPContext::ProcessEdge(const std::pair &edge) BasicBlock *fromBB = edge.first; BasicBlock *toBB = edge.second; + // 检查目标块是否已经可执行 + bool wasAlreadyExecutable = executableBlocks.count(toBB) > 0; + + // 标记目标块为可执行(如果还不是的话) MarkBlockExecutable(toBB); - - // 对于目标块中的所有 Phi 指令,重新评估其值,因为可能有新的前驱被激活 - for (auto &inst_ptr : toBB->getInstructions()) { - if (dynamic_cast(inst_ptr.get())) { - instWorkList.push(inst_ptr.get()); + + // 如果目标块之前就已经可执行,那么需要重新处理其中的phi节点 + // 因为现在有新的前驱变为可执行,phi节点的值可能需要更新 + if (wasAlreadyExecutable) { + for (auto &inst_ptr : toBB->getInstructions()) { + if (dynamic_cast(inst_ptr.get())) { + instWorkList.push(inst_ptr.get()); + } } } + // 如果目标块是新变为可执行的,MarkBlockExecutable已经添加了所有指令 } // 阶段1: 常量传播与折叠 @@ -515,18 +608,29 @@ bool SCCPContext::PropagateConstants(Function *func) { } } + // 初始化函数参数为Bottom(因为它们在编译时是未知的) + for (auto arg : func->getArguments()) { + valueState[arg] = SSAPValue(LatticeVal::Bottom); + if (DEBUG) { + std::cout << "Initializing function argument " << arg->getName() << " to Bottom" << std::endl; + } + } + // 标记入口块为可执行 if (!func->getBasicBlocks().empty()) { MarkBlockExecutable(func->getEntryBlock()); } - // 主循环:处理工作列表直到不动点 + // 主循环:标准的SCCP工作列表算法 + // 交替处理边工作列表和指令工作列表直到不动点 while (!instWorkList.empty() || !edgeWorkList.empty()) { + // 处理所有待处理的CFG边 while (!edgeWorkList.empty()) { ProcessEdge(edgeWorkList.front()); edgeWorkList.pop(); } + // 处理所有待处理的指令 while (!instWorkList.empty()) { Instruction *inst = instWorkList.front(); instWorkList.pop();