880 lines
31 KiB
C++
880 lines
31 KiB
C++
#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 返回 pair,second 为 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
|