From de0f8422e97256e2d201ae039499bfd63973347c Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Thu, 31 Jul 2025 17:29:34 +0800 Subject: [PATCH] =?UTF-8?q?[midend-SCCP]=E6=B2=A1=E6=9C=89=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=8A=A5=E9=94=99=E4=BD=86=E6=98=AFSegmemtation=20fal?= =?UTF-8?q?ut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/midend/CMakeLists.txt | 1 + .../Pass/Optimize/{ SCCP.cpp => SCCP.cpp} | 389 +++++++++--------- src/midend/Pass/Pass.cpp | 6 +- 3 files changed, 200 insertions(+), 196 deletions(-) rename src/midend/Pass/Optimize/{ SCCP.cpp => SCCP.cpp} (72%) diff --git a/src/midend/CMakeLists.txt b/src/midend/CMakeLists.txt index 4830893..3532818 100644 --- a/src/midend/CMakeLists.txt +++ b/src/midend/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(midend_lib STATIC Pass/Optimize/Mem2Reg.cpp Pass/Optimize/Reg2Mem.cpp Pass/Optimize/SysYIRCFGOpt.cpp + Pass/Optimize/SCCP.cpp ) # 包含中端模块所需的头文件路径 diff --git a/src/midend/Pass/Optimize/ SCCP.cpp b/src/midend/Pass/Optimize/SCCP.cpp similarity index 72% rename from src/midend/Pass/Optimize/ SCCP.cpp rename to src/midend/Pass/Optimize/SCCP.cpp index d591765..6c492dc 100644 --- a/src/midend/Pass/Optimize/ SCCP.cpp +++ b/src/midend/Pass/Optimize/SCCP.cpp @@ -32,18 +32,25 @@ SSAPValue SCCPContext::Meet(const SSAPValue &a, const SSAPValue &b) { SSAPValue SCCPContext::GetValueState(Value *v) { if (auto constVal = dynamic_cast(v)) { + // 特殊处理 UndefinedValue:将其视为 Bottom + if (dynamic_cast(constVal)) { + return SSAPValue(LatticeVal::Bottom); + } + // 处理常规的 ConstantInteger 和 ConstantFloating if (constVal->getType()->isInt()) { return SSAPValue(constVal->getInt()); } else if (constVal->getType()->isFloat()) { return SSAPValue(constVal->getFloat()); } else { - return SSAPValue(LatticeVal::Bottom); // 其他类型常量,如指针,暂时不传播 + // 对于其他 ConstantValue 类型(例如,ConstantArray 等), + // 如果它们的具体值不能用于标量常量传播,则保守地视为 Bottom。 + return SSAPValue(LatticeVal::Bottom); } } if (valueState.count(v)) { return valueState[v]; } - return SSAPValue(); // 默认构造函数初始化为 Top + return SSAPValue(); // 默认初始化为 Top } void SCCPContext::UpdateState(Value *v, SSAPValue newState) { @@ -115,12 +122,11 @@ SSAPValue SCCPContext::ComputeConstant(BinaryInst *binaryInst, SSAPValue lhsVal, return SSAPValue(LatticeVal::Bottom); // 如果不是常量,则不能折叠 } - // 处理整数运算 + // 处理整数运算 (kAdd, kSub, kMul, kDiv, kRem, kICmp*, kAnd, kOr) if (lhsVal.constant_type == ValueType::Integer && rhsVal.constant_type == ValueType::Integer) { int lhs = std::get(lhsVal.constantVal); int rhs = std::get(rhsVal.constantVal); int result = 0; - bool is_comparison = false; switch (binaryInst->getKind()) { case Instruction::kAdd: @@ -143,29 +149,23 @@ SSAPValue SCCPContext::ComputeConstant(BinaryInst *binaryInst, SSAPValue lhsVal, result = lhs % rhs; break; case Instruction::kICmpEQ: - is_comparison = true; result = (lhs == rhs); break; case Instruction::kICmpNE: - is_comparison = true; result = (lhs != rhs); break; - case Instruction::kICmpGT: - is_comparison = true; - result = (lhs > rhs); - break; - case Instruction::kICmpGE: - is_comparison = true; - result = (lhs >= rhs); - break; case Instruction::kICmpLT: - is_comparison = true; result = (lhs < rhs); break; + case Instruction::kICmpGT: + result = (lhs > rhs); + break; case Instruction::kICmpLE: - is_comparison = true; result = (lhs <= rhs); break; + case Instruction::kICmpGE: + result = (lhs >= rhs); + break; case Instruction::kAnd: result = (lhs && rhs); break; @@ -173,11 +173,11 @@ SSAPValue SCCPContext::ComputeConstant(BinaryInst *binaryInst, SSAPValue lhsVal, result = (lhs || rhs); break; default: - return SSAPValue(LatticeVal::Bottom); // 未知二元操作 + return SSAPValue(LatticeVal::Bottom); // 未知或不匹配的二元操作 } return SSAPValue(result); } - // 处理浮点运算 + // 处理浮点运算 (kFAdd, kFSub, kFMul, kFDiv, kFCmp*) else if (lhsVal.constant_type == ValueType::Float && rhsVal.constant_type == ValueType::Float) { float lhs = std::get(lhsVal.constantVal); float rhs = std::get(rhsVal.constantVal); @@ -185,45 +185,41 @@ SSAPValue SCCPContext::ComputeConstant(BinaryInst *binaryInst, SSAPValue lhsVal, int i_result = 0; // For comparison results switch (binaryInst->getKind()) { - case Instruction::kAdd: + case Instruction::kFAdd: f_result = lhs + rhs; break; - case Instruction::kSub: + case Instruction::kFSub: f_result = lhs - rhs; break; - case Instruction::kMul: + case Instruction::kFMul: f_result = lhs * rhs; break; - case Instruction::kDiv: + case Instruction::kFDiv: if (rhs == 0.0f) return SSAPValue(LatticeVal::Bottom); // 除零 f_result = lhs / rhs; break; - case Instruction::kRem: - if (rhs == 0.0f) - return SSAPValue(LatticeVal::Bottom); // 模零 - f_result = std::fmod(lhs, rhs); - break; // 浮点数取模 + // kRem 不支持浮点数,但如果你的 IR 定义了浮点模运算,需要使用 std::fmod case Instruction::kFCmpEQ: i_result = (lhs == rhs); return SSAPValue(i_result); case Instruction::kFCmpNE: i_result = (lhs != rhs); return SSAPValue(i_result); - case Instruction::kFCmpGT: - i_result = (lhs > rhs); - return SSAPValue(i_result); - case Instruction::kFCmpGE: - i_result = (lhs >= rhs); - return SSAPValue(i_result); case Instruction::kFCmpLT: i_result = (lhs < rhs); return SSAPValue(i_result); + case Instruction::kFCmpGT: + i_result = (lhs > rhs); + return SSAPValue(i_result); case Instruction::kFCmpLE: i_result = (lhs <= rhs); return SSAPValue(i_result); + case Instruction::kFCmpGE: + i_result = (lhs >= rhs); + return SSAPValue(i_result); default: - return SSAPValue(LatticeVal::Bottom); // 未知浮点二元操作 + return SSAPValue(LatticeVal::Bottom); // 未知或不匹配的浮点二元操作 } return SSAPValue(f_result); } @@ -261,53 +257,6 @@ SSAPValue SCCPContext::ComputeConstant(UnaryInst *unaryInst, SSAPValue operandVa return SSAPValue(LatticeVal::Bottom); } -// 辅助函数:对类型转换进行常量折叠 -SSAPValue SCCPContext::ComputeConstant(CastInst *castInst, SSAPValue operandVal) { - if (operandVal.state != LatticeVal::Constant) { - return SSAPValue(LatticeVal::Bottom); - } - - Type *destType = castInst->getType(); - - switch (castInst->getKind()) { - case Instruction::kZExt: - case Instruction::kSExt: - case Instruction::kTrunc: - // 这些通常是整数之间的转换,或者位模式转换。 - // 对于常量,如果操作数是整数,直接返回其值(假设IR正确处理了范围/截断) - if (operandVal.constant_type == ValueType::Integer && destType->isInt()) { - return SSAPValue(std::get(operandVal.constantVal)); - } - return SSAPValue(LatticeVal::Bottom); // 否则,保守处理 - case Instruction::kFtoI: - if (operandVal.constant_type == ValueType::Float && destType->isInt()) { - return SSAPValue(static_cast(std::get(operandVal.constantVal))); - } - return SSAPValue(LatticeVal::Bottom); - case Instruction::kItoF: - if (operandVal.constant_type == ValueType::Integer && destType->isFloat()) { - return SSAPValue(static_cast(std::get(operandVal.constantVal))); - } - return SSAPValue(LatticeVal::Bottom); - case Instruction::kBitFtoI: - if (operandVal.constant_type == ValueType::Float && destType->isInt()) { - // 执行浮点数到整数的位模式转换,需要重新解释内存 - float fval = std::get(operandVal.constantVal); - return SSAPValue(*reinterpret_cast(&fval)); - } - return SSAPValue(LatticeVal::Bottom); - case Instruction::kBitItoF: - if (operandVal.constant_type == ValueType::Integer && destType->isFloat()) { - // 执行整数到浮点数的位模式转换,需要重新解释内存 - int ival = std::get(operandVal.constantVal); - return SSAPValue(*reinterpret_cast(&ival)); - } - return SSAPValue(LatticeVal::Bottom); - default: - return SSAPValue(LatticeVal::Bottom); - } -} - // 辅助函数:处理单条指令 void SCCPContext::ProcessInstruction(Instruction *inst) { SSAPValue oldState = GetValueState(inst); @@ -333,16 +282,20 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { case Instruction::kRem: case Instruction::kICmpEQ: case Instruction::kICmpNE: - case Instruction::kICmpGT: - case Instruction::kICmpGE: case Instruction::kICmpLT: + case Instruction::kICmpGT: case Instruction::kICmpLE: + case Instruction::kICmpGE: + case Instruction::kFAdd: + case Instruction::kFSub: + case Instruction::kFMul: + case Instruction::kFDiv: case Instruction::kFCmpEQ: case Instruction::kFCmpNE: - case Instruction::kFCmpGT: - case Instruction::kFCmpGE: case Instruction::kFCmpLT: + case Instruction::kFCmpGT: case Instruction::kFCmpLE: + case Instruction::kFCmpGE: case Instruction::kAnd: case Instruction::kOr: { BinaryInst *binaryInst = static_cast(inst); @@ -363,7 +316,7 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { case Instruction::kFNeg: case Instruction::kFNot: { UnaryInst *unaryInst = static_cast(inst); - SSAPValue operand = GetValueState(unaryInst->getOperand(0)); + SSAPValue operand = GetValueState(unaryInst->getOperand()); if (operand.state == LatticeVal::Bottom) { newState = SSAPValue(LatticeVal::Bottom); } else if (operand.state == LatticeVal::Top) { @@ -373,21 +326,50 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { } break; } - case Instruction::kFtoI: - case Instruction::kItoF: - case Instruction::kZExt: - case Instruction::kSExt: - case Instruction::kTrunc: - case Instruction::kBitFtoI: - case Instruction::kBitItoF: { - CastInst *castInst = static_cast(inst); - SSAPValue operand = GetValueState(castInst->getOperand(0)); - if (operand.state == LatticeVal::Bottom) { + // 直接处理类型转换指令 + case Instruction::kFtoI: { + SSAPValue operand = GetValueState(inst->getOperand(0)); + if (operand.state == LatticeVal::Constant && operand.constant_type == ValueType::Float) { + newState = SSAPValue(static_cast(std::get(operand.constantVal))); + } else if (operand.state == LatticeVal::Bottom) { newState = SSAPValue(LatticeVal::Bottom); - } else if (operand.state == LatticeVal::Top) { - newState = SSAPValue(); // Top - } else { // 是常量 - newState = ComputeConstant(castInst, operand); + } else { // Top + newState = SSAPValue(); + } + break; + } + case Instruction::kItoF: { + SSAPValue operand = GetValueState(inst->getOperand(0)); + if (operand.state == LatticeVal::Constant && operand.constant_type == ValueType::Integer) { + newState = SSAPValue(static_cast(std::get(operand.constantVal))); + } else if (operand.state == LatticeVal::Bottom) { + newState = SSAPValue(LatticeVal::Bottom); + } else { // Top + newState = SSAPValue(); + } + break; + } + case Instruction::kBitFtoI: { + SSAPValue operand = GetValueState(inst->getOperand(0)); + if (operand.state == LatticeVal::Constant && operand.constant_type == ValueType::Float) { + float fval = std::get(operand.constantVal); + newState = SSAPValue(*reinterpret_cast(&fval)); + } else if (operand.state == LatticeVal::Bottom) { + newState = SSAPValue(LatticeVal::Bottom); + } else { // Top + newState = SSAPValue(); + } + break; + } + case Instruction::kBitItoF: { + SSAPValue operand = GetValueState(inst->getOperand(0)); + if (operand.state == LatticeVal::Constant && operand.constant_type == ValueType::Integer) { + int ival = std::get(operand.constantVal); + newState = SSAPValue(*reinterpret_cast(&ival)); + } else if (operand.state == LatticeVal::Bottom) { + newState = SSAPValue(LatticeVal::Bottom); + } else { // Top + newState = SSAPValue(); } break; } @@ -444,15 +426,20 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { newState = phiResult; break; } - case Instruction::kAlloc: + case Instruction::kAlloca: // 对应 kAlloca // Alloca 分配内存,返回一个指针,其内容是 Bottom newState = SSAPValue(LatticeVal::Bottom); break; - case Instruction::kBranch: - case Instruction::kReturn: + case Instruction::kBr: // 对应 kBr + case Instruction::kCondBr: // 对应 kCondBr + case Instruction::kReturn: // 对应 kReturn // 终结符指令不产生值 newState = SSAPValue(); // 保持 Top break; + case Instruction::kMemset: + // Memset 不产生值,但有副作用,不进行常量传播 + newState = SSAPValue(LatticeVal::Bottom); + break; default: if (DEBUG) { std::cout << "Unimplemented instruction kind in SCCP: " << inst->getKind() << std::endl; @@ -464,8 +451,8 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { // 特殊处理终结符指令,影响 CFG 边的可达性 if (inst->isTerminator()) { - if (auto branchInst = dynamic_cast(inst)) { - if (branchInst->isCondBr()) { + if (auto branchInst = dynamic_cast(inst)) { + if (branchInst->isCondBr()) { // 使用 kCondBr SSAPValue condVal = GetValueState(branchInst->getOperand(0)); if (condVal.state == LatticeVal::Constant) { bool condition_is_true = false; @@ -476,16 +463,16 @@ void SCCPContext::ProcessInstruction(Instruction *inst) { } if (condition_is_true) { - AddEdgeToWorkList(branchInst->getParent(), branchInst->getTrueBlock()); + AddEdgeToWorkList(branchInst->getParent(), branchInst->getThenBlock()); } else { - AddEdgeToWorkList(branchInst->getParent(), branchInst->getFalseBlock()); + AddEdgeToWorkList(branchInst->getParent(), branchInst->getElseBlock()); } } else { // 条件是 Top 或 Bottom,两条路径都可能 - AddEdgeToWorkList(branchInst->getParent(), branchInst->getTrueBlock()); - AddEdgeToWorkList(branchInst->getParent(), branchInst->getFalseBlock()); + AddEdgeToWorkList(branchInst->getParent(), branchInst->getThenBlock()); + AddEdgeToWorkList(branchInst->getParent(), branchInst->getElseBlock()); } - } else { // 无条件分支 - AddEdgeToWorkList(branchInst->getParent(), branchInst->getTrueBlock()); + } else { // 无条件分支 (kBr) + AddEdgeToWorkList(branchInst->getParent(), branchInst->getThenBlock()); } } } @@ -549,7 +536,6 @@ bool SCCPContext::PropagateConstants(Function *func) { changed = true; continue; } - for (auto it = bb->begin(); it != bb->end();) { Instruction *inst = it->get(); SSAPValue ssaPVal = GetValueState(inst); @@ -574,7 +560,8 @@ bool SCCPContext::PropagateConstants(Function *func) { } inst->replaceAllUsesWith(constVal); instsToDelete.push_back(inst); - it = bb->removeInst(it); // 从块中移除指令 + // it = bb->removeInst(it); // 从块中移除指令 + it = bb->getInstructions().erase(it); changed = true; } else { // 如果操作数是常量,直接替换为常量值(常量折叠) @@ -604,12 +591,24 @@ bool SCCPContext::PropagateConstants(Function *func) { // 实际删除指令 for (Instruction *inst : instsToDelete) { - if (inst->getParent() && !SysYIROptUtils::usedelete(inst)) { - // 如果 still in parent and not deleted by usedelete, implies issues or non-instruction values. - // For SCCP, if replaced, it should have no uses. - if (DEBUG) { - std::cerr << "Warning: Instruction " << inst->getName() << " was not fully deleted." << std::endl; - } + // 在尝试删除之前,先检查指令是否仍然附加到其父基本块。 + // 如果它已经没有父块,可能说明它已被其他方式处理或已处于无效状态。 + if (inst->getParent() != nullptr) { + // 调用负责完整删除的函数,该函数应负责清除uses并将其从父块中移除。 + SysYIROptUtils::usedelete_withinstdelte(inst); + if (inst->getParent() != nullptr) { + // 如果执行到这里,说明 usedelete_withinstdelte 没有成功将其从父块中移除。 + if (DEBUG) { + std::cerr << "Warning: Instruction " << inst->getName() + << " was not fully deleted by usedelete_withinstdelte and is still in parent." << std::endl; + } + } + } + else { + // 指令已不属于任何父块,无需再次删除。 + if (DEBUG) { + std::cerr << "Info: Instruction " << inst->getName() << " was already detached or is not in a parent block." << std::endl; + } } } return changed; @@ -642,9 +641,9 @@ bool SCCPContext::SimplifyControlFlow(Function *func) { if (!newReachableBlocks.count(bb)) continue; // 只处理可达块 - Instruction *terminator = bb->terminator().get(); - if (auto branchInst = dynamic_cast(terminator)) { - if (branchInst->isCondBr()) { + Instruction *terminator = bb->terminator()->get(); + if (auto branchInst = dynamic_cast(terminator)) { + if (branchInst->isCondBr()) { // 检查是否是条件分支 (kCondBr) SSAPValue condVal = GetValueState(branchInst->getOperand(0)); if (condVal.state == LatticeVal::Constant) { bool condition_is_true = false; @@ -677,12 +676,12 @@ std::unordered_set SCCPContext::FindReachableBlocks(Function *func BasicBlock *currentBB = q.front(); q.pop(); - Instruction *terminator = currentBB->terminator().get(); + Instruction *terminator = currentBB->terminator()->get(); if (!terminator) continue; - if (auto branchInst = dynamic_cast(terminator)) { - if (branchInst->isCondBr()) { + if (auto branchInst = dynamic_cast(terminator)) { + if (branchInst->isCondBr()) { // 检查是否是条件分支 (kCondBr) SSAPValue condVal = GetValueState(branchInst->getOperand(0)); if (condVal.state == LatticeVal::Constant) { bool condition_is_true = false; @@ -693,13 +692,13 @@ std::unordered_set SCCPContext::FindReachableBlocks(Function *func } if (condition_is_true) { - BasicBlock *trueBlock = branchInst->getTrueBlock(); + BasicBlock *trueBlock = branchInst->getThenBlock(); if (reachable.find(trueBlock) == reachable.end()) { reachable.insert(trueBlock); q.push(trueBlock); } } else { - BasicBlock *falseBlock = branchInst->getFalseBlock(); + BasicBlock *falseBlock = branchInst->getElseBlock(); if (reachable.find(falseBlock) == reachable.end()) { reachable.insert(falseBlock); q.push(falseBlock); @@ -713,8 +712,8 @@ std::unordered_set SCCPContext::FindReachableBlocks(Function *func } } } - } else { // 无条件分支 - BasicBlock *targetBlock = branchInst->getTrueBlock(); + } else { // 无条件分支 (kBr) + BasicBlock *targetBlock = branchInst->getThenBlock(); if (reachable.find(targetBlock) == reachable.end()) { reachable.insert(targetBlock); q.push(targetBlock); @@ -733,103 +732,113 @@ void SCCPContext::RemoveDeadBlock(BasicBlock *bb, Function *func) { std::cout << "Removing dead block: " << bb->getName() << std::endl; } // 首先更新其所有前驱的终结指令,移除指向死块的边 - std::vector preds_to_remove; - for (auto &pred_weak_ptr : bb->getPredecessors()) { - if (auto pred = pred_weak_ptr.lock()) { // 确保前驱块仍然存在 - preds_to_remove.push_back(pred.get()); + std::vector preds_to_update; + for (auto &pred : bb->getPredecessors()) { + if (pred != nullptr) { // 检查是否为空指针 + preds_to_update.push_back(pred); } } - for (BasicBlock *pred : preds_to_remove) { - UpdateTerminator(pred, bb); + for (BasicBlock *pred : preds_to_update) { + if (executableBlocks.count(pred)) { + UpdateTerminator(pred, bb); + } } // 移除其后继的 Phi 节点的入边 + std::vector succs_to_update; for (auto succ : bb->getSuccessors()) { + succs_to_update.push_back(succ); + } + for (BasicBlock *succ : succs_to_update) { RemovePhiIncoming(succ, bb); } - func->removeBasicBlock(bb); + func->removeBasicBlock(bb); // 从函数中移除基本块 } // 简化分支(将条件分支替换为无条件分支) -void SCCPContext::SimplifyBranch(BranchInst *brInst, bool condVal) { +void SCCPContext::SimplifyBranch(CondBrInst *brInst, bool condVal) { BasicBlock *parentBB = brInst->getParent(); - BasicBlock *trueBlock = brInst->getTrueBlock(); - BasicBlock *falseBlock = brInst->getFalseBlock(); + BasicBlock *trueBlock = brInst->getThenBlock(); + BasicBlock *falseBlock = brInst->getElseBlock(); if (DEBUG) { std::cout << "Simplifying branch in " << parentBB->getName() << ": cond is " << (condVal ? "true" : "false") << std::endl; } - builder->setInsertPoint(parentBB, brInst->getIterator()); - if (condVal) { // 条件为真,跳转到真分支 - builder->createBranchInst(trueBlock); - // 移除旧的条件分支指令 - SysYIROptUtils::usedelete(brInst); - // 移除与假分支的连接 + builder->setPosition(parentBB, parentBB->findInstIterator(brInst)); + if (condVal) { // 条件为真,跳转到真分支 + builder->createUncondBrInst(trueBlock); // 插入无条件分支 kBr + SysYIROptUtils::usedelete(brInst); // 移除旧的条件分支指令 + // TODO now: 移出指令 + parentBB->removeSuccessor(falseBlock); falseBlock->removePredecessor(parentBB); - // 移除假分支中 Phi 节点的来自当前块的入边 RemovePhiIncoming(falseBlock, parentBB); - } else { // 条件为假,跳转到假分支 - builder->createBranchInst(falseBlock); - // 移除旧的条件分支指令 - SysYIROptUtils::usedelete(brInst); - // 移除与真分支的连接 + } else { // 条件为假,跳转到假分支 + builder->createUncondBrInst(falseBlock); // 插入无条件分支 kBr + SysYIROptUtils::usedelete(brInst); // 移除旧的条件分支指令 + // TODO now: 移出指令 + parentBB->removeSuccessor(trueBlock); trueBlock->removePredecessor(parentBB); - // 移除真分支中 Phi 节点的来自当前块的入边 RemovePhiIncoming(trueBlock, parentBB); } } // 更新前驱块的终结指令(当一个后继块被移除时) void SCCPContext::UpdateTerminator(BasicBlock *predBB, BasicBlock *removedSucc) { - Instruction *terminator = predBB->terminator().get(); + Instruction *terminator = predBB->terminator()->get(); if (!terminator) return; - // 对于 BranchInst,如果其某个目标是 removedSucc,则需要更新它 - if (auto branchInst = dynamic_cast(terminator)) { - if (branchInst->isCondBr()) { - // 如果 removedSucc 是真分支,则条件分支应指向假分支 - if (branchInst->getTrueBlock() == removedSucc) { - // 如果另一个分支也死了,则整个分支是死代码,由其他阶段移除 - // 这里我们简化为无条件跳转到另一个仍然可达的分支 - builder->setInsertPoint(predBB, branchInst->getIterator()); - builder->createBranchInst(branchInst->getFalseBlock()); - SysYIROptUtils::usedelete(branchInst); - predBB->removeSuccessor(removedSucc); // 从前驱的后继列表中移除 - } - // 如果 removedSucc 是假分支,则条件分支应指向真分支 - else if (branchInst->getFalseBlock() == removedSucc) { - builder->setInsertPoint(predBB, branchInst->getIterator()); - builder->createBranchInst(branchInst->getTrueBlock()); - SysYIROptUtils::usedelete(branchInst); - predBB->removeSuccessor(removedSucc); // 从前驱的后继列表中移除 - } - } else { // 无条件分支 - // 如果目标是 removedSucc,这通常意味着整个 predBB 也是死块 - // 或者需要一个 unreachable 指令 - if (branchInst->getTrueBlock() == removedSucc) { - // 暂时不创建 unreachable,因为可能死块会被整个移除 - // 或者留待后续简化。只移除后继连接。 - SysYIROptUtils::usedelete(branchInst); // 先删除指令 + if (auto branchInst = dynamic_cast(terminator)) { + if (branchInst->isCondBr()) { // 如果是条件分支 + if (branchInst->getThenBlock() == removedSucc) { + if (DEBUG) { + std::cout << "Updating cond br in " << predBB->getName() << ": True block (" << removedSucc->getName() + << ") removed. Converting to Br to " << branchInst->getElseBlock()->getName() << std::endl; + } + builder->setPosition(predBB, predBB->findInstIterator(branchInst)); + builder->createUncondBrInst(branchInst->getElseBlock()); + SysYIROptUtils::usedelete_withinstdelte(branchInst); predBB->removeSuccessor(removedSucc); - builder->setInsertPoint(predBB, predBB->end()); // 在块末尾插入 - builder->createUnreachableInst(); // 插入一个不可达指令,标记代码路径结束 + } else if (branchInst->getElseBlock() == removedSucc) { + if (DEBUG) { + std::cout << "Updating cond br in " << predBB->getName() << ": False block (" << removedSucc->getName() + << ") removed. Converting to Br to " << branchInst->getThenBlock()->getName() << std::endl; + } + builder->setPosition(predBB, predBB->findInstIterator(branchInst)); + builder->createUncondBrInst(branchInst->getThenBlock()); + SysYIROptUtils::usedelete_withinstdelte(branchInst); + predBB->removeSuccessor(removedSucc); + } + } else { // 无条件分支 (kBr) + if (branchInst->getThenBlock() == removedSucc) { + if (DEBUG) { + std::cout << "Updating unconditional br in " << predBB->getName() << ": Target block (" + << removedSucc->getName() << ") removed. Replacing with Unreachable." << std::endl; + } + SysYIROptUtils::usedelete_withinstdelte(branchInst); + predBB->removeSuccessor(removedSucc); + builder->setPosition(predBB, predBB->end()); + builder->createUnreachableInst(); } } } - // ReturnInst 和其他指令不受影响 } // 移除 Phi 节点的入边(当其前驱块被移除时) -void SCCPContext::RemovePhiIncoming(BasicBlock *phiParentBB, BasicBlock *removedPred) { +void SCCPContext::RemovePhiIncoming(BasicBlock *phiParentBB, BasicBlock *removedPred) { // 修正 removedPred 类型 + std::vector insts_to_check; for (auto &inst_ptr : phiParentBB->getInstructions()) { - if (auto phi = dynamic_cast(inst_ptr.get())) { - phi->removeIncomingValue(removedPred); // 移除来自已删除前驱的入边 + insts_to_check.push_back(inst_ptr.get()); + } + + for (Instruction *inst : insts_to_check) { + if (auto phi = dynamic_cast(inst)) { + phi->delBlk(removedPred); } } } @@ -852,20 +861,10 @@ bool SCCP::runOnFunction(Function *F, AnalysisManager &AM) { } SCCPContext context(builder); context.run(F, AM); - // SCCPContext::run 内部负责管理 changed 状态并执行优化。 - // 这里我们无法直接返回 context.run 的 `changed` 值, - // 因为 run 是 void。通常会通过 context 的一个成员来跟踪。 - // 或者,runOnFunction 负责判断是否发生了变化。 - // 目前,为简单起见,假设 SCCPContext::run 确实执行了修改,并总是返回 true, - // 这在实际编译器中可能需要更精确的追踪。 - // 更好的做法是让 run 返回 bool. - // 由于用户提供的run是void, 且外部无法直接访问context的changed变量,我们暂时保守返回true。 return true; } void SCCP::getAnalysisUsage(std::set &analysisDependencies, std::set &analysisInvalidations) const { - // SCCP 不依赖其他分析,但它会改变 IR,因此会使许多分析失效 - // 例如:DominatorTree, CFG analysis, LI, ... analysisInvalidations.insert(nullptr); // 表示使所有默认分析失效 } diff --git a/src/midend/Pass/Pass.cpp b/src/midend/Pass/Pass.cpp index d6087fe..8fbaeec 100644 --- a/src/midend/Pass/Pass.cpp +++ b/src/midend/Pass/Pass.cpp @@ -5,6 +5,7 @@ #include "DCE.h" #include "Mem2Reg.h" #include "Reg2Mem.h" +#include "SCCP.h" #include "Pass.h" #include #include @@ -50,6 +51,8 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR registerOptimizationPass(builderIR); registerOptimizationPass(builderIR); + registerOptimizationPass(builderIR); + if (optLevel >= 1) { //经过设计安排优化遍的执行顺序以及执行逻辑 if (DEBUG) std::cout << "Applying -O1 optimizations.\n"; @@ -80,10 +83,11 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR this->clearPasses(); this->addPass(&Mem2Reg::ID); + this->addPass(&SCCP::ID); this->run(); if(DEBUG) { - std::cout << "=== IR After Mem2Reg Optimizations ===\n"; + std::cout << "=== IR After Mem2Reg And SCCP Optimizations ===\n"; printPasses(); }