[midend-SCCP]没有编译报错但是Segmemtation falut
This commit is contained in:
@ -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
|
||||
)
|
||||
|
||||
# 包含中端模块所需的头文件路径
|
||||
|
||||
@ -32,18 +32,25 @@ SSAPValue SCCPContext::Meet(const SSAPValue &a, const SSAPValue &b) {
|
||||
|
||||
SSAPValue SCCPContext::GetValueState(Value *v) {
|
||||
if (auto constVal = dynamic_cast<ConstantValue *>(v)) {
|
||||
// 特殊处理 UndefinedValue:将其视为 Bottom
|
||||
if (dynamic_cast<UndefinedValue *>(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<int>(lhsVal.constantVal);
|
||||
int rhs = std::get<int>(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<float>(lhsVal.constantVal);
|
||||
float rhs = std::get<float>(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<int>(operandVal.constantVal));
|
||||
}
|
||||
return SSAPValue(LatticeVal::Bottom); // 否则,保守处理
|
||||
case Instruction::kFtoI:
|
||||
if (operandVal.constant_type == ValueType::Float && destType->isInt()) {
|
||||
return SSAPValue(static_cast<int>(std::get<float>(operandVal.constantVal)));
|
||||
}
|
||||
return SSAPValue(LatticeVal::Bottom);
|
||||
case Instruction::kItoF:
|
||||
if (operandVal.constant_type == ValueType::Integer && destType->isFloat()) {
|
||||
return SSAPValue(static_cast<float>(std::get<int>(operandVal.constantVal)));
|
||||
}
|
||||
return SSAPValue(LatticeVal::Bottom);
|
||||
case Instruction::kBitFtoI:
|
||||
if (operandVal.constant_type == ValueType::Float && destType->isInt()) {
|
||||
// 执行浮点数到整数的位模式转换,需要重新解释内存
|
||||
float fval = std::get<float>(operandVal.constantVal);
|
||||
return SSAPValue(*reinterpret_cast<int *>(&fval));
|
||||
}
|
||||
return SSAPValue(LatticeVal::Bottom);
|
||||
case Instruction::kBitItoF:
|
||||
if (operandVal.constant_type == ValueType::Integer && destType->isFloat()) {
|
||||
// 执行整数到浮点数的位模式转换,需要重新解释内存
|
||||
int ival = std::get<int>(operandVal.constantVal);
|
||||
return SSAPValue(*reinterpret_cast<float *>(&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<BinaryInst *>(inst);
|
||||
@ -363,7 +316,7 @@ void SCCPContext::ProcessInstruction(Instruction *inst) {
|
||||
case Instruction::kFNeg:
|
||||
case Instruction::kFNot: {
|
||||
UnaryInst *unaryInst = static_cast<UnaryInst *>(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<CastInst *>(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<int>(std::get<float>(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<float>(std::get<int>(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<float>(operand.constantVal);
|
||||
newState = SSAPValue(*reinterpret_cast<int *>(&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<int>(operand.constantVal);
|
||||
newState = SSAPValue(*reinterpret_cast<float *>(&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<BranchInst *>(inst)) {
|
||||
if (branchInst->isCondBr()) {
|
||||
if (auto branchInst = dynamic_cast<CondBrInst *>(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<BranchInst *>(terminator)) {
|
||||
if (branchInst->isCondBr()) {
|
||||
Instruction *terminator = bb->terminator()->get();
|
||||
if (auto branchInst = dynamic_cast<CondBrInst *>(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<BasicBlock *> 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<BranchInst *>(terminator)) {
|
||||
if (branchInst->isCondBr()) {
|
||||
if (auto branchInst = dynamic_cast<CondBrInst *>(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<BasicBlock *> 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<BasicBlock *> 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<BasicBlock *> 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<BasicBlock *> 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<BasicBlock *> 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<BranchInst *>(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<CondBrInst *>(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<Instruction *> insts_to_check;
|
||||
for (auto &inst_ptr : phiParentBB->getInstructions()) {
|
||||
if (auto phi = dynamic_cast<PhiInst *>(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<PhiInst *>(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<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const {
|
||||
// SCCP 不依赖其他分析,但它会改变 IR,因此会使许多分析失效
|
||||
// 例如:DominatorTree, CFG analysis, LI, ...
|
||||
analysisInvalidations.insert(nullptr); // 表示使所有默认分析失效
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "DCE.h"
|
||||
#include "Mem2Reg.h"
|
||||
#include "Reg2Mem.h"
|
||||
#include "SCCP.h"
|
||||
#include "Pass.h"
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
@ -50,6 +51,8 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
||||
registerOptimizationPass<Mem2Reg>(builderIR);
|
||||
registerOptimizationPass<Reg2Mem>(builderIR);
|
||||
|
||||
registerOptimizationPass<SCCP>(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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user