Files
mysysy/src/midend/Pass/Optimize/SCCP.cpp

880 lines
31 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "SCCP.h"
#include "Dom.h"
#include "Liveness.h"
#include <algorithm>
#include <cassert>
#include <cmath> // For std::fmod, std::fabs
#include <limits> // For std::numeric_limits
namespace sysy {
// Pass ID for SCCP
void *SCCP::ID = (void *)&SCCP::ID;
// SCCPContext methods
SSAPValue SCCPContext::Meet(const SSAPValue &a, const SSAPValue &b) {
if (a.state == LatticeVal::Bottom || b.state == LatticeVal::Bottom) {
return SSAPValue(LatticeVal::Bottom);
}
if (a.state == LatticeVal::Top) {
return b;
}
if (b.state == LatticeVal::Top) {
return a;
}
// Both are constants
if (a.constant_type != b.constant_type) {
return SSAPValue(LatticeVal::Bottom); // 不同类型的常量,结果为 Bottom
}
if (a.constantVal == b.constantVal) {
return a; // 相同常量
}
return SSAPValue(LatticeVal::Bottom); // 相同类型但值不同,结果为 Bottom
}
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 {
// 对于其他 ConstantValue 类型例如ConstantArray 等),
// 如果它们的具体值不能用于标量常量传播,则保守地视为 Bottom。
return SSAPValue(LatticeVal::Bottom);
}
}
if (valueState.count(v)) {
return valueState[v];
}
return SSAPValue(); // 默认初始化为 Top
}
void SCCPContext::UpdateState(Value *v, SSAPValue newState) {
SSAPValue oldState = GetValueState(v);
if (newState != oldState) {
if (DEBUG) {
std::cout << "Updating state for " << v->getName() << " from (";
if (oldState.state == LatticeVal::Top)
std::cout << "Top";
else if (oldState.state == LatticeVal::Constant) {
if (oldState.constant_type == ValueType::Integer)
std::cout << "Const<int>(" << std::get<int>(oldState.constantVal) << ")";
else
std::cout << "Const<float>(" << std::get<float>(oldState.constantVal) << ")";
} else
std::cout << "Bottom";
std::cout << ") to (";
if (newState.state == LatticeVal::Top)
std::cout << "Top";
else if (newState.state == LatticeVal::Constant) {
if (newState.constant_type == ValueType::Integer)
std::cout << "Const<int>(" << std::get<int>(newState.constantVal) << ")";
else
std::cout << "Const<float>(" << std::get<float>(newState.constantVal) << ")";
} else
std::cout << "Bottom";
std::cout << ")" << std::endl;
}
valueState[v] = newState;
// 如果状态发生变化,将所有使用者添加到指令工作列表
for (auto &use_ptr : v->getUses()) {
if (auto userInst = dynamic_cast<Instruction *>(use_ptr->getUser())) {
instWorkList.push(userInst);
}
}
}
}
void SCCPContext::AddEdgeToWorkList(BasicBlock *fromBB, BasicBlock *toBB) {
// 检查边是否已经访问过,防止重复处理
if (visitedCFGEdges.count({fromBB, toBB})) {
return;
}
visitedCFGEdges.insert({fromBB, toBB});
if (DEBUG) {
std::cout << "Adding edge to worklist: " << fromBB->getName() << " -> " << toBB->getName() << std::endl;
}
edgeWorkList.push({fromBB, toBB});
}
void SCCPContext::MarkBlockExecutable(BasicBlock *block) {
if (executableBlocks.insert(block).second) { // insert 返回 pairsecond 为 true 表示插入成功
if (DEBUG) {
std::cout << "Marking block " << block->getName() << " as executable." << std::endl;
}
// 将新可执行块中的所有指令添加到指令工作列表
for (auto &inst_ptr : block->getInstructions()) {
instWorkList.push(inst_ptr.get());
}
}
}
// 辅助函数:对二元操作进行常量折叠
SSAPValue SCCPContext::ComputeConstant(BinaryInst *binaryInst, SSAPValue lhsVal, SSAPValue rhsVal) {
// 确保操作数是常量
if (lhsVal.state != LatticeVal::Constant || rhsVal.state != LatticeVal::Constant) {
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;
switch (binaryInst->getKind()) {
case Instruction::kAdd:
result = lhs + rhs;
break;
case Instruction::kSub:
result = lhs - rhs;
break;
case Instruction::kMul:
result = lhs * rhs;
break;
case Instruction::kDiv:
if (rhs == 0)
return SSAPValue(LatticeVal::Bottom); // 除零
result = lhs / rhs;
break;
case Instruction::kRem:
if (rhs == 0)
return SSAPValue(LatticeVal::Bottom); // 模零
result = lhs % rhs;
break;
case Instruction::kICmpEQ:
result = (lhs == rhs);
break;
case Instruction::kICmpNE:
result = (lhs != rhs);
break;
case Instruction::kICmpLT:
result = (lhs < rhs);
break;
case Instruction::kICmpGT:
result = (lhs > rhs);
break;
case Instruction::kICmpLE:
result = (lhs <= rhs);
break;
case Instruction::kICmpGE:
result = (lhs >= rhs);
break;
case Instruction::kAnd:
result = (lhs && rhs);
break;
case Instruction::kOr:
result = (lhs || rhs);
break;
default:
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);
float f_result = 0.0f;
int i_result = 0; // For comparison results
switch (binaryInst->getKind()) {
case Instruction::kFAdd:
f_result = lhs + rhs;
break;
case Instruction::kFSub:
f_result = lhs - rhs;
break;
case Instruction::kFMul:
f_result = lhs * rhs;
break;
case Instruction::kFDiv:
if (rhs == 0.0f)
return SSAPValue(LatticeVal::Bottom); // 除零
f_result = 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::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(f_result);
}
return SSAPValue(LatticeVal::Bottom); // 类型不匹配或不支持的类型组合
}
// 辅助函数:对一元操作进行常量折叠
SSAPValue SCCPContext::ComputeConstant(UnaryInst *unaryInst, SSAPValue operandVal) {
if (operandVal.state != LatticeVal::Constant) {
return SSAPValue(LatticeVal::Bottom);
}
if (operandVal.constant_type == ValueType::Integer) {
int val = std::get<int>(operandVal.constantVal);
switch (unaryInst->getKind()) {
case Instruction::kAdd:
return SSAPValue(val);
case Instruction::kNeg:
return SSAPValue(-val);
case Instruction::kNot:
return SSAPValue(!val);
default:
return SSAPValue(LatticeVal::Bottom);
}
} else if (operandVal.constant_type == ValueType::Float) {
float val = std::get<float>(operandVal.constantVal);
switch (unaryInst->getKind()) {
case Instruction::kAdd:
return SSAPValue(val);
case Instruction::kFNeg:
return SSAPValue(-val);
case Instruction::kFNot:
return SSAPValue(static_cast<int>(val == 0.0f)); // 浮点数非0.0f 为真,其他为假
default:
return SSAPValue(LatticeVal::Bottom);
}
}
return SSAPValue(LatticeVal::Bottom);
}
// 辅助函数:处理单条指令
void SCCPContext::ProcessInstruction(Instruction *inst) {
SSAPValue oldState = GetValueState(inst);
SSAPValue newState;
if (!executableBlocks.count(inst->getParent())) {
// 如果指令所在的块不可执行,其值应保持 Top
// 除非它之前已经是 Bottom因为 Bottom 是单调的
if (oldState.state != LatticeVal::Bottom) {
newState = SSAPValue(); // Top
} else {
newState = oldState; // 保持 Bottom
}
UpdateState(inst, newState);
return; // 不处理不可达块中的指令的实际值
}
switch (inst->getKind()) {
case Instruction::kAdd:
case Instruction::kSub:
case Instruction::kMul:
case Instruction::kDiv:
case Instruction::kRem:
case Instruction::kICmpEQ:
case Instruction::kICmpNE:
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::kFCmpLT:
case Instruction::kFCmpGT:
case Instruction::kFCmpLE:
case Instruction::kFCmpGE:
case Instruction::kAnd:
case Instruction::kOr: {
BinaryInst *binaryInst = static_cast<BinaryInst *>(inst);
SSAPValue lhs = GetValueState(binaryInst->getOperand(0));
SSAPValue rhs = GetValueState(binaryInst->getOperand(1));
// 如果任一操作数是 Bottom结果就是 Bottom
if (lhs.state == LatticeVal::Bottom || rhs.state == LatticeVal::Bottom) {
newState = SSAPValue(LatticeVal::Bottom);
} else if (lhs.state == LatticeVal::Top || rhs.state == LatticeVal::Top) {
newState = SSAPValue(); // Top
} else { // 都是常量
newState = ComputeConstant(binaryInst, lhs, rhs);
}
break;
}
case Instruction::kNeg:
case Instruction::kNot:
case Instruction::kFNeg:
case Instruction::kFNot: {
UnaryInst *unaryInst = static_cast<UnaryInst *>(inst);
SSAPValue operand = GetValueState(unaryInst->getOperand());
if (operand.state == LatticeVal::Bottom) {
newState = SSAPValue(LatticeVal::Bottom);
} else if (operand.state == LatticeVal::Top) {
newState = SSAPValue(); // Top
} else { // 是常量
newState = ComputeConstant(unaryInst, operand);
}
break;
}
// 直接处理类型转换指令
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 { // 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;
}
case Instruction::kLoad: {
// 对于 Load 指令,除非我们有特殊的别名分析,否则假定为 Bottom
// 或者如果它加载的是一个已知常量地址的全局常量
Value *ptr = inst->getOperand(0);
if (auto globalVal = dynamic_cast<GlobalValue *>(ptr)) {
// 如果 GlobalValue 有初始化器,并且它是常量,我们可以传播
// 这需要额外的逻辑来检查 globalVal 的初始化器
// 暂时保守地设置为 Bottom
newState = SSAPValue(LatticeVal::Bottom);
} else {
newState = SSAPValue(LatticeVal::Bottom);
}
break;
}
case Instruction::kStore:
// Store 指令不产生值,其 SSAPValue 不重要
newState = SSAPValue(); // 保持 Top
break;
case Instruction::kCall:
// 大多数 Call 指令都假定为 Bottom除非是纯函数且所有参数都是常量
newState = SSAPValue(LatticeVal::Bottom);
break;
case Instruction::kGetElementPtr: {
// GEP 指令计算地址,通常其结果值(地址指向的内容)是 Bottom
// 除非所有索引和基指针都是常量,指向一个确定常量值的内存位置
bool all_ops_constant = true;
for (unsigned i = 0; i < inst->getNumOperands(); ++i) {
if (GetValueState(inst->getOperand(i)).state != LatticeVal::Constant) {
all_ops_constant = false;
break;
}
}
// 即使地址是常量,地址处的内容通常不是。所以通常是 Bottom
newState = SSAPValue(LatticeVal::Bottom);
break;
}
case Instruction::kPhi: {
PhiInst *phi = static_cast<PhiInst *>(inst);
SSAPValue phiResult = SSAPValue(); // 初始为 Top
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则提前退出
}
}
newState = phiResult;
break;
}
case Instruction::kAlloca: // 对应 kAlloca
// Alloca 分配内存,返回一个指针,其内容是 Bottom
newState = SSAPValue(LatticeVal::Bottom);
break;
case Instruction::kBr: // 对应 kBr
case Instruction::kCondBr: // 对应 kCondBr
case Instruction::kReturn: // 对应 kReturn
case Instruction::kUnreachable: // 对应 kUnreachable
// 终结符指令不产生值
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;
}
newState = SSAPValue(LatticeVal::Bottom); // 未知指令保守处理为 Bottom
break;
}
UpdateState(inst, newState);
// 特殊处理终结符指令,影响 CFG 边的可达性
if (inst->isTerminator()) {
if (inst->isBranch()) {
if (inst->isCondBr()) { // 使用 kCondBr
CondBrInst *branchInst = static_cast<CondBrInst *>(inst);
SSAPValue condVal = GetValueState(branchInst->getOperand(0));
if (condVal.state == LatticeVal::Constant) {
bool condition_is_true = false;
if (condVal.constant_type == ValueType::Integer) {
condition_is_true = (std::get<int>(condVal.constantVal) != 0);
} else if (condVal.constant_type == ValueType::Float) {
condition_is_true = (std::get<float>(condVal.constantVal) != 0.0f);
}
if (condition_is_true) {
AddEdgeToWorkList(branchInst->getParent(), branchInst->getThenBlock());
} else {
AddEdgeToWorkList(branchInst->getParent(), branchInst->getElseBlock());
}
} else { // 条件是 Top 或 Bottom两条路径都可能
AddEdgeToWorkList(branchInst->getParent(), branchInst->getThenBlock());
AddEdgeToWorkList(branchInst->getParent(), branchInst->getElseBlock());
}
} else { // 无条件分支 (kBr)
UncondBrInst *branchInst = static_cast<UncondBrInst *>(inst);
AddEdgeToWorkList(branchInst->getParent(), branchInst->getBlock());
}
}
}
}
// 辅助函数:处理单条控制流边
void SCCPContext::ProcessEdge(const std::pair<BasicBlock *, BasicBlock *> &edge) {
BasicBlock *fromBB = edge.first;
BasicBlock *toBB = edge.second;
MarkBlockExecutable(toBB);
// 对于目标块中的所有 Phi 指令,重新评估其值,因为可能有新的前驱被激活
for (auto &inst_ptr : toBB->getInstructions()) {
if (dynamic_cast<PhiInst *>(inst_ptr.get())) {
instWorkList.push(inst_ptr.get());
}
}
}
// 阶段1: 常量传播与折叠
bool SCCPContext::PropagateConstants(Function *func) {
bool changed = false;
// 初始化:所有值 Top所有块不可执行
for (auto &bb_ptr : func->getBasicBlocks()) {
executableBlocks.erase(bb_ptr.get());
for (auto &inst_ptr : bb_ptr->getInstructions()) {
valueState[inst_ptr.get()] = SSAPValue(); // Top
}
}
// 标记入口块为可执行
if (!func->getBasicBlocks().empty()) {
MarkBlockExecutable(func->getEntryBlock());
}
// 主循环:处理工作列表直到不动点
while (!instWorkList.empty() || !edgeWorkList.empty()) {
while (!edgeWorkList.empty()) {
ProcessEdge(edgeWorkList.front());
edgeWorkList.pop();
}
while (!instWorkList.empty()) {
Instruction *inst = instWorkList.front();
instWorkList.pop();
ProcessInstruction(inst);
}
}
// 应用常量替换和死代码消除
std::vector<Instruction *> instsToDelete;
for (auto &bb_ptr : func->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (!executableBlocks.count(bb)) {
// 整个块是死块,标记所有指令删除
for (auto &inst_ptr : bb->getInstructions()) {
instsToDelete.push_back(inst_ptr.get());
}
changed = true;
continue;
}
for (auto it = bb->begin(); it != bb->end();) {
Instruction *inst = it->get();
SSAPValue ssaPVal = GetValueState(inst);
if (ssaPVal.state == LatticeVal::Constant) {
ConstantValue *constVal = nullptr;
if (ssaPVal.constant_type == ValueType::Integer) {
constVal = ConstantInteger::get(std::get<int>(ssaPVal.constantVal));
} else if (ssaPVal.constant_type == ValueType::Float) {
constVal = ConstantFloating::get(std::get<float>(ssaPVal.constantVal));
} else {
constVal = UndefinedValue::get(inst->getType()); // 不应发生
}
if (DEBUG) {
std::cout << "Replacing " << inst->getName() << " with constant ";
if (ssaPVal.constant_type == ValueType::Integer)
std::cout << std::get<int>(ssaPVal.constantVal);
else
std::cout << std::get<float>(ssaPVal.constantVal);
std::cout << std::endl;
}
inst->replaceAllUsesWith(constVal);
instsToDelete.push_back(inst);
++it;
changed = true;
} else {
// 如果操作数是常量,直接替换为常量值(常量折叠)
for (unsigned i = 0; i < inst->getNumOperands(); ++i) {
Value *operand = inst->getOperand(i);
SSAPValue opVal = GetValueState(operand);
if (opVal.state == LatticeVal::Constant) {
ConstantValue *constOp = nullptr;
if (opVal.constant_type == ValueType::Integer) {
constOp = ConstantInteger::get(std::get<int>(opVal.constantVal));
} else if (opVal.constant_type == ValueType::Float) {
constOp = ConstantFloating::get(std::get<float>(opVal.constantVal));
} else {
constOp = UndefinedValue::get(operand->getType());
}
if (constOp != operand) {
inst->setOperand(i, constOp);
changed = true;
}
}
}
++it;
}
}
}
// 实际删除指令
// TODO: 删除的逻辑需要考虑修改
for (Instruction *inst : instsToDelete) {
// 在尝试删除之前,先检查指令是否仍然附加到其父基本块。
// 如果它已经没有父块,可能说明它已被其他方式处理或已处于无效状态。
if (inst->getParent() != nullptr) {
// 调用负责完整删除的函数该函数应负责清除uses并将其从父块中移除。
SysYIROptUtils::usedelete(inst);
}
else {
// 指令已不属于任何父块,无需再次删除。
if (DEBUG) {
std::cerr << "Info: Instruction " << inst->getName() << " was already detached or is not in a parent block." << std::endl;
}
}
}
return changed;
}
// 阶段2: 控制流简化
bool SCCPContext::SimplifyControlFlow(Function *func) {
bool changed = false;
// 重新确定可达块,因为 PropagateConstants 可能改变了分支条件
std::unordered_set<BasicBlock *> newReachableBlocks = FindReachableBlocks(func);
// 移除不可达块
std::vector<BasicBlock *> blocksToDelete;
for (auto &bb_ptr : func->getBasicBlocks()) {
if (bb_ptr.get() == func->getEntryBlock())
continue; // 入口块不能删除
if (newReachableBlocks.find(bb_ptr.get()) == newReachableBlocks.end()) {
blocksToDelete.push_back(bb_ptr.get());
changed = true;
}
}
for (BasicBlock *bb : blocksToDelete) {
RemoveDeadBlock(bb, func);
}
// 简化分支指令
for (auto &bb_ptr : func->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (!newReachableBlocks.count(bb))
continue; // 只处理可达块
Instruction *terminator = bb->terminator()->get();
if (terminator->isBranch()) {
if (terminator->isCondBr()) { // 检查是否是条件分支 (kCondBr)
CondBrInst *branchInst = static_cast<CondBrInst *>(terminator);
SSAPValue condVal = GetValueState(branchInst->getOperand(0));
if (condVal.state == LatticeVal::Constant) {
bool condition_is_true = false;
if (condVal.constant_type == ValueType::Integer) {
condition_is_true = (std::get<int>(condVal.constantVal) != 0);
} else if (condVal.constant_type == ValueType::Float) {
condition_is_true = (std::get<float>(condVal.constantVal) != 0.0f);
}
SimplifyBranch(branchInst, condition_is_true);
changed = true;
}
}
}
}
return changed;
}
// 查找所有可达的基本块 (基于常量条件)
std::unordered_set<BasicBlock *> SCCPContext::FindReachableBlocks(Function *func) {
std::unordered_set<BasicBlock *> reachable;
std::queue<BasicBlock *> q;
if (func->getEntryBlock()) {
q.push(func->getEntryBlock());
reachable.insert(func->getEntryBlock());
}
while (!q.empty()) {
BasicBlock *currentBB = q.front();
q.pop();
Instruction *terminator = currentBB->terminator()->get();
if (!terminator)
continue;
if (terminator->isBranch()) {
if (terminator->isCondBr()) { // 检查是否是条件分支 (kCondBr)
CondBrInst *branchInst = static_cast<CondBrInst *>(terminator);
SSAPValue condVal = GetValueState(branchInst->getOperand(0));
if (condVal.state == LatticeVal::Constant) {
bool condition_is_true = false;
if (condVal.constant_type == ValueType::Integer) {
condition_is_true = (std::get<int>(condVal.constantVal) != 0);
} else if (condVal.constant_type == ValueType::Float) {
condition_is_true = (std::get<float>(condVal.constantVal) != 0.0f);
}
if (condition_is_true) {
BasicBlock *trueBlock = branchInst->getThenBlock();
if (reachable.find(trueBlock) == reachable.end()) {
reachable.insert(trueBlock);
q.push(trueBlock);
}
} else {
BasicBlock *falseBlock = branchInst->getElseBlock();
if (reachable.find(falseBlock) == reachable.end()) {
reachable.insert(falseBlock);
q.push(falseBlock);
}
}
} else { // 条件是 Top 或 Bottom两条路径都可达
for (auto succ : branchInst->getSuccessors()) {
if (reachable.find(succ) == reachable.end()) {
reachable.insert(succ);
q.push(succ);
}
}
}
} else { // 无条件分支 (kBr)
UncondBrInst *branchInst = static_cast<UncondBrInst *>(terminator);
BasicBlock *targetBlock = branchInst->getBlock();
if (reachable.find(targetBlock) == reachable.end()) {
reachable.insert(targetBlock);
q.push(targetBlock);
}
}
} else if (terminator->isReturn() || terminator->isUnreachable()) {
// ReturnInst 没有后继,不需要处理
// UnreachableInst 也没有后继,不需要处理
}
}
return reachable;
}
// 移除死块
void SCCPContext::RemoveDeadBlock(BasicBlock *bb, Function *func) {
if (DEBUG) {
std::cout << "Removing dead block: " << bb->getName() << std::endl;
}
// 首先更新其所有前驱的终结指令,移除指向死块的边
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_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);
succ->removePredecessor(bb);
}
func->removeBasicBlock(bb); // 从函数中移除基本块
}
// 简化分支(将条件分支替换为无条件分支)
void SCCPContext::SimplifyBranch(CondBrInst *brInst, bool condVal) {
BasicBlock *parentBB = brInst->getParent();
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->setPosition(parentBB, parentBB->findInstIterator(brInst));
if (condVal) { // 条件为真,跳转到真分支
builder->createUncondBrInst(trueBlock); // 插入无条件分支 kBr
SysYIROptUtils::usedelete(brInst); // 移除旧的条件分支指令
parentBB->removeSuccessor(falseBlock);
falseBlock->removePredecessor(parentBB);
RemovePhiIncoming(falseBlock, parentBB);
} else { // 条件为假,跳转到假分支
builder->createUncondBrInst(falseBlock); // 插入无条件分支 kBr
SysYIROptUtils::usedelete(brInst); // 移除旧的条件分支指令
parentBB->removeSuccessor(trueBlock);
trueBlock->removePredecessor(parentBB);
RemovePhiIncoming(trueBlock, parentBB);
}
}
// 更新前驱块的终结指令(当一个后继块被移除时)
void SCCPContext::UpdateTerminator(BasicBlock *predBB, BasicBlock *removedSucc) {
Instruction *terminator = predBB->terminator()->get();
if (!terminator)
return;
if (terminator->isBranch()) {
if (terminator->isCondBr()) { // 如果是条件分支
CondBrInst *branchInst = static_cast<CondBrInst *>(terminator);
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(branchInst);
predBB->removeSuccessor(removedSucc);
} 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(branchInst);
predBB->removeSuccessor(removedSucc);
}
} else { // 无条件分支 (kBr)
UncondBrInst *branchInst = static_cast<UncondBrInst *>(terminator);
if (branchInst->getBlock() == removedSucc) {
if (DEBUG) {
std::cout << "Updating unconditional br in " << predBB->getName() << ": Target block ("
<< removedSucc->getName() << ") removed. Replacing with Unreachable." << std::endl;
}
SysYIROptUtils::usedelete(branchInst);
predBB->removeSuccessor(removedSucc);
builder->setPosition(predBB, predBB->end());
builder->createUnreachableInst();
}
}
}
}
// 移除 Phi 节点的入边(当其前驱块被移除时)
void SCCPContext::RemovePhiIncoming(BasicBlock *phiParentBB, BasicBlock *removedPred) { // 修正 removedPred 类型
std::vector<Instruction *> insts_to_check;
for (auto &inst_ptr : phiParentBB->getInstructions()) {
insts_to_check.push_back(inst_ptr.get());
}
for (Instruction *inst : insts_to_check) {
if (auto phi = dynamic_cast<PhiInst *>(inst)) {
phi->delBlk(removedPred);
}
}
}
// 运行 SCCP 优化
void SCCPContext::run(Function *func, AnalysisManager &AM) {
bool changed_constant_propagation = PropagateConstants(func);
bool changed_control_flow = SimplifyControlFlow(func);
// 如果任何一个阶段修改了 IR标记分析结果为失效
if (changed_constant_propagation || changed_control_flow) {
// AM.invalidate(); // 假设有这样的方法来使所有分析结果失效
}
}
// SCCP Pass methods
bool SCCP::runOnFunction(Function *F, AnalysisManager &AM) {
if (DEBUG) {
std::cout << "Running SCCP on function: " << F->getName() << std::endl;
}
SCCPContext context(builder);
context.run(F, AM);
return true;
}
void SCCP::getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const {
// analysisInvalidations.insert(nullptr); // 表示使所有默认分析失效
analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID); // 支配树可能受影响
analysisInvalidations.insert(&LivenessAnalysisPass::ID); // 活跃性分析很可能失效
}
} // namespace sysy