Merge branch 'midend' into midend-LoopAnalysis
This commit is contained in:
79
src/midend/Pass/Optimize/BuildCFG.cpp
Normal file
79
src/midend/Pass/Optimize/BuildCFG.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "BuildCFG.h"
|
||||
#include "Dom.h"
|
||||
#include "Liveness.h"
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
void *BuildCFG::ID = (void *)&BuildCFG::ID; // 定义唯一的 Pass ID
|
||||
|
||||
// 声明Pass的分析使用
|
||||
void BuildCFG::getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const {
|
||||
// BuildCFG不依赖其他分析
|
||||
// analysisDependencies.insert(&DominatorTreeAnalysisPass::ID); // 错误的例子
|
||||
|
||||
// BuildCFG会使所有依赖于CFG的分析结果失效,所以它必须声明这些失效
|
||||
analysisInvalidations.insert(&DominatorTreeAnalysisPass::ID);
|
||||
analysisInvalidations.insert(&LivenessAnalysisPass::ID);
|
||||
}
|
||||
|
||||
bool BuildCFG::runOnFunction(Function *F, AnalysisManager &AM) {
|
||||
if (DEBUG) {
|
||||
std::cout << "Running BuildCFG pass on function: " << F->getName() << std::endl;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
// 1. 清空所有基本块的前驱和后继列表
|
||||
for (auto &bb : F->getBasicBlocks()) {
|
||||
bb->clearPredecessors();
|
||||
bb->clearSuccessors();
|
||||
}
|
||||
|
||||
// 2. 遍历每个基本块,重建CFG
|
||||
for (auto &bb : F->getBasicBlocks()) {
|
||||
// 获取基本块的最后一条指令
|
||||
auto &inst = *bb->terminator();
|
||||
Instruction *termInst = inst.get();
|
||||
// 确保基本块有终结指令
|
||||
if (!termInst) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 根据终结指令类型,建立前驱后继关系
|
||||
if (termInst->isBranch()) {
|
||||
// 无条件跳转
|
||||
if (termInst->isUnconditional()) {
|
||||
auto brInst = dynamic_cast<UncondBrInst *>(termInst);
|
||||
BasicBlock *succ = dynamic_cast<BasicBlock *>(brInst->getBlock());
|
||||
assert(succ && "Branch instruction's target must be a BasicBlock");
|
||||
bb->addSuccessor(succ);
|
||||
succ->addPredecessor(bb.get());
|
||||
changed = true;
|
||||
|
||||
// 条件跳转
|
||||
} else if (termInst->isConditional()) {
|
||||
auto brInst = dynamic_cast<CondBrInst *>(termInst);
|
||||
BasicBlock *trueSucc = dynamic_cast<BasicBlock *>(brInst->getThenBlock());
|
||||
BasicBlock *falseSucc = dynamic_cast<BasicBlock *>(brInst->getElseBlock());
|
||||
|
||||
assert(trueSucc && falseSucc && "Branch instruction's targets must be BasicBlocks");
|
||||
|
||||
bb->addSuccessor(trueSucc);
|
||||
trueSucc->addPredecessor(bb.get());
|
||||
bb->addSuccessor(falseSucc);
|
||||
falseSucc->addPredecessor(bb.get());
|
||||
changed = true;
|
||||
}
|
||||
} else if (auto retInst = dynamic_cast<ReturnInst *>(termInst)) {
|
||||
// RetInst没有后继,无需处理
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
} // namespace sysy
|
||||
145
src/midend/Pass/Optimize/LargeArrayToGlobal.cpp
Normal file
145
src/midend/Pass/Optimize/LargeArrayToGlobal.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include "../../include/midend/Pass/Optimize/LargeArrayToGlobal.h"
|
||||
#include "../../IR.h"
|
||||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace sysy {
|
||||
|
||||
// Helper function to convert type to string
|
||||
static std::string typeToString(Type *type) {
|
||||
if (!type) return "null";
|
||||
|
||||
switch (type->getKind()) {
|
||||
case Type::kInt:
|
||||
return "int";
|
||||
case Type::kFloat:
|
||||
return "float";
|
||||
case Type::kPointer:
|
||||
return "ptr";
|
||||
case Type::kArray: {
|
||||
auto *arrayType = type->as<ArrayType>();
|
||||
return "[" + std::to_string(arrayType->getNumElements()) + " x " +
|
||||
typeToString(arrayType->getElementType()) + "]";
|
||||
}
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void *LargeArrayToGlobalPass::ID = &LargeArrayToGlobalPass::ID;
|
||||
|
||||
bool LargeArrayToGlobalPass::runOnModule(Module *M, AnalysisManager &AM) {
|
||||
bool changed = false;
|
||||
|
||||
if (!M) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Collect all alloca instructions from all functions
|
||||
std::vector<std::pair<AllocaInst*, Function*>> allocasToConvert;
|
||||
|
||||
for (auto &funcPair : M->getFunctions()) {
|
||||
Function *F = funcPair.second.get();
|
||||
if (!F || F->getBasicBlocks().begin() == F->getBasicBlocks().end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto &BB : F->getBasicBlocks()) {
|
||||
for (auto &inst : BB->getInstructions()) {
|
||||
if (auto *alloca = dynamic_cast<AllocaInst*>(inst.get())) {
|
||||
Type *allocatedType = alloca->getAllocatedType();
|
||||
|
||||
// Calculate the size of the allocated type
|
||||
unsigned size = calculateTypeSize(allocatedType);
|
||||
if(DEBUG){
|
||||
// Debug: print size information
|
||||
std::cout << "LargeArrayToGlobalPass: Found alloca with size " << size
|
||||
<< " for type " << typeToString(allocatedType) << std::endl;
|
||||
}
|
||||
|
||||
// Convert arrays of 1KB (1024 bytes) or larger to global variables
|
||||
if (size >= 1024) {
|
||||
if(DEBUG)
|
||||
std::cout << "LargeArrayToGlobalPass: Converting array of size " << size << " to global" << std::endl;
|
||||
allocasToConvert.emplace_back(alloca, F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the collected alloca instructions to global variables
|
||||
for (auto [alloca, F] : allocasToConvert) {
|
||||
convertAllocaToGlobal(alloca, F, M);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
unsigned LargeArrayToGlobalPass::calculateTypeSize(Type *type) {
|
||||
if (!type) return 0;
|
||||
|
||||
switch (type->getKind()) {
|
||||
case Type::kInt:
|
||||
case Type::kFloat:
|
||||
return 4;
|
||||
case Type::kPointer:
|
||||
return 8;
|
||||
case Type::kArray: {
|
||||
auto *arrayType = type->as<ArrayType>();
|
||||
return arrayType->getNumElements() * calculateTypeSize(arrayType->getElementType());
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LargeArrayToGlobalPass::convertAllocaToGlobal(AllocaInst *alloca, Function *F, Module *M) {
|
||||
Type *allocatedType = alloca->getAllocatedType();
|
||||
|
||||
// Create a unique name for the global variable
|
||||
std::string globalName = generateUniqueGlobalName(alloca, F);
|
||||
|
||||
// Create the global variable - GlobalValue expects pointer type
|
||||
Type *pointerType = Type::getPointerType(allocatedType);
|
||||
GlobalValue *globalVar = M->createGlobalValue(globalName, pointerType);
|
||||
|
||||
if (!globalVar) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace all uses of the alloca with the global variable
|
||||
alloca->replaceAllUsesWith(globalVar);
|
||||
|
||||
// Remove the alloca instruction from its basic block
|
||||
for (auto &BB : F->getBasicBlocks()) {
|
||||
auto &instructions = BB->getInstructions();
|
||||
for (auto it = instructions.begin(); it != instructions.end(); ++it) {
|
||||
if (it->get() == alloca) {
|
||||
instructions.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string LargeArrayToGlobalPass::generateUniqueGlobalName(AllocaInst *alloca, Function *F) {
|
||||
std::string baseName = alloca->getName();
|
||||
if (baseName.empty()) {
|
||||
baseName = "array";
|
||||
}
|
||||
|
||||
// Ensure uniqueness by appending function name and counter
|
||||
static std::unordered_map<std::string, int> nameCounter;
|
||||
std::string key = F->getName() + "." + baseName;
|
||||
|
||||
int counter = nameCounter[key]++;
|
||||
std::ostringstream oss;
|
||||
oss << key << "." << counter;
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
} // namespace sysy
|
||||
@@ -148,8 +148,8 @@ void Reg2MemContext::rewritePhis(Function *func) {
|
||||
// 1. 为 Phi 指令的每个入边,在前驱块的末尾插入 Store 指令
|
||||
// PhiInst 假设有 getIncomingValues() 和 getIncomingBlocks()
|
||||
for (unsigned i = 0; i < phiInst->getNumIncomingValues(); ++i) { // 假设 PhiInst 是通过操作数来管理入边的
|
||||
Value *incomingValue = phiInst->getValue(i); // 获取入值
|
||||
BasicBlock *incomingBlock = phiInst->getBlock(i); // 获取对应的入块
|
||||
Value *incomingValue = phiInst->getIncomingValue(i); // 获取入值
|
||||
BasicBlock *incomingBlock = phiInst->getIncomingBlock(i); // 获取对应的入块
|
||||
|
||||
// 在入块的跳转指令之前插入 StoreInst
|
||||
// 需要找到 incomingBlock 的终结指令 (Terminator Instruction)
|
||||
|
||||
@@ -468,6 +468,22 @@ void SCCPContext::ProcessInstruction(Instruction *inst) {
|
||||
return; // 不处理不可达块中的指令的实际值
|
||||
}
|
||||
|
||||
if(DEBUG) {
|
||||
std::cout << "Processing instruction: " << inst->getName() << " in block " << inst->getParent()->getName() << std::endl;
|
||||
std::cout << "Old state: ";
|
||||
if (oldState.state == LatticeVal::Top) {
|
||||
std::cout << "Top";
|
||||
} else if (oldState.state == LatticeVal::Constant) {
|
||||
if (oldState.constant_type == ValueType::Integer) {
|
||||
std::cout << "Const<int>(" << std::get<int>(oldState.constantVal) << ")";
|
||||
} else {
|
||||
std::cout << "Const<float>(" << std::get<float>(oldState.constantVal) << ")";
|
||||
}
|
||||
} else {
|
||||
std::cout << "Bottom";
|
||||
}
|
||||
}
|
||||
|
||||
switch (inst->getKind()) {
|
||||
case Instruction::kAdd:
|
||||
case Instruction::kSub:
|
||||
@@ -815,19 +831,71 @@ void SCCPContext::ProcessInstruction(Instruction *inst) {
|
||||
}
|
||||
case Instruction::kPhi: {
|
||||
PhiInst *phi = static_cast<PhiInst *>(inst);
|
||||
if(DEBUG) {
|
||||
std::cout << "Processing Phi node: " << phi->getName() << std::endl;
|
||||
}
|
||||
// 标准SCCP的phi节点处理:
|
||||
// 只考虑可执行前驱,但要保证单调性
|
||||
SSAPValue currentPhiState = GetValueState(phi);
|
||||
SSAPValue phiResult = SSAPValue(); // 初始为 Top
|
||||
|
||||
bool hasAnyExecutablePred = false;
|
||||
|
||||
for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) {
|
||||
Value *incomingVal = phi->getIncomingValue(i);
|
||||
BasicBlock *incomingBlock = phi->getIncomingBlock(i);
|
||||
|
||||
if (executableBlocks.count(incomingBlock)) { // 仅考虑可执行前驱
|
||||
phiResult = Meet(phiResult, GetValueState(incomingVal));
|
||||
if (phiResult.state == LatticeVal::Bottom)
|
||||
break; // 如果已经 Bottom,则提前退出
|
||||
|
||||
if (executableBlocks.count(incomingBlock)) {
|
||||
hasAnyExecutablePred = true;
|
||||
Value *incomingVal = phi->getIncomingValue(i);
|
||||
SSAPValue incomingState = GetValueState(incomingVal);
|
||||
if(DEBUG) {
|
||||
std::cout << " Incoming from block " << incomingBlock->getName()
|
||||
<< " with value " << incomingVal->getName() << " state: ";
|
||||
if (incomingState.state == LatticeVal::Top)
|
||||
std::cout << "Top";
|
||||
else if (incomingState.state == LatticeVal::Constant) {
|
||||
if (incomingState.constant_type == ValueType::Integer)
|
||||
std::cout << "Const<int>(" << std::get<int>(incomingState.constantVal) << ")";
|
||||
else
|
||||
std::cout << "Const<float>(" << std::get<float>(incomingState.constantVal) << ")";
|
||||
} else
|
||||
std::cout << "Bottom";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
phiResult = Meet(phiResult, incomingState);
|
||||
|
||||
if (phiResult.state == LatticeVal::Bottom) {
|
||||
break; // 提前退出优化
|
||||
}
|
||||
}
|
||||
// 不可执行前驱暂时被忽略
|
||||
// 这是标准SCCP的做法,依赖于单调性保证正确性
|
||||
}
|
||||
|
||||
if (!hasAnyExecutablePred) {
|
||||
// 没有可执行前驱,保持Top状态
|
||||
newState = SSAPValue();
|
||||
} else {
|
||||
// 关键修复:使用严格的单调性
|
||||
// 确保phi的值只能从Top -> Constant -> Bottom单向变化
|
||||
if (currentPhiState.state == LatticeVal::Top) {
|
||||
// 从Top状态,可以变为任何计算结果
|
||||
newState = phiResult;
|
||||
} else if (currentPhiState.state == LatticeVal::Constant) {
|
||||
// 从Constant状态,只能保持相同常量或变为Bottom
|
||||
if (phiResult.state == LatticeVal::Constant &&
|
||||
currentPhiState.constantVal == phiResult.constantVal &&
|
||||
currentPhiState.constant_type == phiResult.constant_type) {
|
||||
// 保持相同的常量
|
||||
newState = currentPhiState;
|
||||
} else {
|
||||
// 不同的值,必须变为Bottom
|
||||
newState = SSAPValue(LatticeVal::Bottom);
|
||||
}
|
||||
} else {
|
||||
// 已经是Bottom,保持Bottom
|
||||
newState = currentPhiState;
|
||||
}
|
||||
}
|
||||
newState = phiResult;
|
||||
break;
|
||||
}
|
||||
case Instruction::kAlloca: // 对应 kAlloca
|
||||
@@ -884,6 +952,22 @@ void SCCPContext::ProcessInstruction(Instruction *inst) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
std::cout << "New state: ";
|
||||
if (newState.state == LatticeVal::Top) {
|
||||
std::cout << "Top";
|
||||
} else if (newState.state == LatticeVal::Constant) {
|
||||
if (newState.constant_type == ValueType::Integer) {
|
||||
std::cout << "Const<int>(" << std::get<int>(newState.constantVal) << ")";
|
||||
} else {
|
||||
std::cout << "Const<float>(" << std::get<float>(newState.constantVal) << ")";
|
||||
}
|
||||
} else {
|
||||
std::cout << "Bottom";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助函数:处理单条控制流边
|
||||
@@ -891,14 +975,22 @@ void SCCPContext::ProcessEdge(const std::pair<BasicBlock *, BasicBlock *> &edge)
|
||||
BasicBlock *fromBB = edge.first;
|
||||
BasicBlock *toBB = edge.second;
|
||||
|
||||
// 检查目标块是否已经可执行
|
||||
bool wasAlreadyExecutable = executableBlocks.count(toBB) > 0;
|
||||
|
||||
// 标记目标块为可执行(如果还不是的话)
|
||||
MarkBlockExecutable(toBB);
|
||||
|
||||
// 对于目标块中的所有 Phi 指令,重新评估其值,因为可能有新的前驱被激活
|
||||
for (auto &inst_ptr : toBB->getInstructions()) {
|
||||
if (dynamic_cast<PhiInst *>(inst_ptr.get())) {
|
||||
instWorkList.push(inst_ptr.get());
|
||||
|
||||
// 如果目标块之前就已经可执行,那么需要重新处理其中的phi节点
|
||||
// 因为现在有新的前驱变为可执行,phi节点的值可能需要更新
|
||||
if (wasAlreadyExecutable) {
|
||||
for (auto &inst_ptr : toBB->getInstructions()) {
|
||||
if (dynamic_cast<PhiInst *>(inst_ptr.get())) {
|
||||
instWorkList.push(inst_ptr.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 如果目标块是新变为可执行的,MarkBlockExecutable已经添加了所有指令
|
||||
}
|
||||
|
||||
// 阶段1: 常量传播与折叠
|
||||
@@ -913,18 +1005,29 @@ bool SCCPContext::PropagateConstants(Function *func) {
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化函数参数为Bottom(因为它们在编译时是未知的)
|
||||
for (auto arg : func->getArguments()) {
|
||||
valueState[arg] = SSAPValue(LatticeVal::Bottom);
|
||||
if (DEBUG) {
|
||||
std::cout << "Initializing function argument " << arg->getName() << " to Bottom" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 标记入口块为可执行
|
||||
if (!func->getBasicBlocks().empty()) {
|
||||
MarkBlockExecutable(func->getEntryBlock());
|
||||
}
|
||||
|
||||
// 主循环:处理工作列表直到不动点
|
||||
// 主循环:标准的SCCP工作列表算法
|
||||
// 交替处理边工作列表和指令工作列表直到不动点
|
||||
while (!instWorkList.empty() || !edgeWorkList.empty()) {
|
||||
// 处理所有待处理的CFG边
|
||||
while (!edgeWorkList.empty()) {
|
||||
ProcessEdge(edgeWorkList.front());
|
||||
edgeWorkList.pop();
|
||||
}
|
||||
|
||||
// 处理所有待处理的指令
|
||||
while (!instWorkList.empty()) {
|
||||
Instruction *inst = instWorkList.front();
|
||||
instWorkList.pop();
|
||||
@@ -1243,7 +1346,7 @@ void SCCPContext::RemovePhiIncoming(BasicBlock *phiParentBB, BasicBlock *removed
|
||||
|
||||
for (Instruction *inst : insts_to_check) {
|
||||
if (auto phi = dynamic_cast<PhiInst *>(inst)) {
|
||||
phi->delBlk(removedPred);
|
||||
phi->removeIncomingBlock(removedPred);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ bool SysYCFGOptUtils::SysYDelInstAfterBr(Function *func) {
|
||||
++Branchiter;
|
||||
while (Branchiter != instructions.end()) {
|
||||
changed = true;
|
||||
Branchiter = instructions.erase(Branchiter);
|
||||
Branchiter = SysYIROptUtils::usedelete(Branchiter); // 删除指令
|
||||
}
|
||||
|
||||
if (Branch) { // 更新前驱后继关系
|
||||
@@ -77,6 +77,11 @@ bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
|
||||
bool changed = false;
|
||||
|
||||
for (auto blockiter = func->getBasicBlocks().begin(); blockiter != func->getBasicBlocks().end();) {
|
||||
// 检查当前块是是不是entry块
|
||||
if( blockiter->get() == func->getEntryBlock() ) {
|
||||
blockiter++;
|
||||
continue; // 跳过入口块
|
||||
}
|
||||
if (blockiter->get()->getNumSuccessors() == 1) {
|
||||
// 如果当前块只有一个后继块
|
||||
// 且后继块只有一个前驱块
|
||||
@@ -86,7 +91,7 @@ bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
|
||||
BasicBlock *block = blockiter->get();
|
||||
BasicBlock *nextBlock = blockiter->get()->getSuccessors()[0];
|
||||
// auto nextarguments = nextBlock->getArguments();
|
||||
// 删除br指令
|
||||
// 删除block的br指令
|
||||
if (block->getNumInstructions() != 0) {
|
||||
auto thelastinstinst = block->terminator();
|
||||
if (thelastinstinst->get()->isUnconditional()) {
|
||||
@@ -98,14 +103,21 @@ bool SysYCFGOptUtils::SysYBlockMerge(Function *func) {
|
||||
if (brinst->getThenBlock() == brinst->getElseBlock()) {
|
||||
thelastinstinst = SysYIROptUtils::usedelete(thelastinstinst);
|
||||
}
|
||||
else{
|
||||
assert(false && "SysYBlockMerge: unexpected conditional branch with different then and else blocks");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 将后继块的指令移动到当前块
|
||||
// 并将后继块的父指针改为当前块
|
||||
for (auto institer = nextBlock->begin(); institer != nextBlock->end();) {
|
||||
institer->get()->setParent(block);
|
||||
block->getInstructions().emplace_back(institer->release());
|
||||
institer = nextBlock->getInstructions().erase(institer);
|
||||
// institer->get()->setParent(block);
|
||||
// block->getInstructions().emplace_back(institer->release());
|
||||
// 用usedelete删除会导致use关系被删除我只希望移动指令到当前块
|
||||
// institer = SysYIROptUtils::usedelete(institer);
|
||||
// institer = nextBlock->getInstructions().erase(institer);
|
||||
institer = nextBlock->moveInst(institer, block->getInstructions().end(), block);
|
||||
|
||||
}
|
||||
// 更新前驱后继关系,类似树节点操作
|
||||
block->removeSuccessor(nextBlock);
|
||||
@@ -189,7 +201,7 @@ bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) {
|
||||
break;
|
||||
}
|
||||
// 将这个 Phi 节点中来自不可达前驱(unreachableBlock)的输入参数删除
|
||||
dynamic_cast<PhiInst *>(phiInstPtr.get())->delBlk(unreachableBlock);
|
||||
dynamic_cast<PhiInst *>(phiInstPtr.get())->removeIncomingBlock(unreachableBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,13 +300,12 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::function<Value *(Value *, BasicBlock *)> getUltimateSourceValue = [&](Value *val,
|
||||
BasicBlock *currentDefBlock) -> Value * {
|
||||
// 如果值不是指令,例如常量或函数参数,则它本身就是最终来源
|
||||
if (auto instr = dynamic_cast<Instruction *>(val)) { // Assuming Value* has a method to check if it's an instruction
|
||||
std::function<Value *(Value *, BasicBlock *)> getUltimateSourceValue = [&](Value *val, BasicBlock *currentDefBlock) -> Value * {
|
||||
|
||||
if(!dynamic_cast<Instruction *>(val)) {
|
||||
// 如果 val 不是指令,直接返回它
|
||||
return val;
|
||||
}
|
||||
|
||||
Instruction *inst = dynamic_cast<Instruction *>(val);
|
||||
// 如果定义指令不在任何空块中,它就是最终来源
|
||||
if (!emptyBlockRedirectMap.count(currentDefBlock)) {
|
||||
@@ -311,7 +322,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
// 找到在空块链中导致 currentDefBlock 的那个前驱块
|
||||
if (emptyBlockRedirectMap.count(incomingBlock) || incomingBlock == currentBlock) {
|
||||
// 递归追溯该传入值
|
||||
return getUltimateSourceValue(phi->getIncomingValue(incomingBlock), incomingBlock);
|
||||
return getUltimateSourceValue(phi->getValfromBlk(incomingBlock), incomingBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,7 +365,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
|
||||
if (actualEmptyPredecessorOfS) {
|
||||
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
||||
Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS);
|
||||
Value *valueFromEmptyPredecessor = phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||
|
||||
// 追溯这个值,找到它在非空块中的最终来源
|
||||
// currentBlock 是 P
|
||||
@@ -364,12 +375,13 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
|
||||
// 替换 Phi 节点的传入块和传入值
|
||||
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
||||
phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
// phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
phiInst->replaceIncomingBlock(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
} else {
|
||||
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
||||
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
||||
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
||||
phiInst->removeIncoming(actualEmptyPredecessorOfS);
|
||||
phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -421,7 +433,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
|
||||
if (actualEmptyPredecessorOfS) {
|
||||
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
||||
Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS);
|
||||
Value *valueFromEmptyPredecessor = phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||
|
||||
// 追溯这个值,找到它在非空块中的最终来源
|
||||
// currentBlock 是 P
|
||||
@@ -431,12 +443,13 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
|
||||
// 替换 Phi 节点的传入块和传入值
|
||||
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
||||
phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
// phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
phiInst->replaceIncomingBlock(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
} else {
|
||||
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
||||
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
||||
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
||||
phiInst->removeIncoming(actualEmptyPredecessorOfS);
|
||||
phiInst->removeIncomingBlock(actualEmptyPredecessorOfS);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -481,7 +494,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
|
||||
if (actualEmptyPredecessorOfS) {
|
||||
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
||||
Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS);
|
||||
Value *valueFromEmptyPredecessor = phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||
|
||||
// 追溯这个值,找到它在非空块中的最终来源
|
||||
// currentBlock 是 P
|
||||
@@ -491,12 +504,13 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
||||
|
||||
// 替换 Phi 节点的传入块和传入值
|
||||
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
||||
phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
// phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
phiInst->replaceIncomingBlock(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||
} else {
|
||||
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
||||
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
||||
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
||||
phiInst->removeIncoming(actualEmptyPredecessorOfS);
|
||||
phiInst->removeIncomingBlock(actualEmptyPredecessorOfS);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -647,7 +661,7 @@ bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder *pBuilder) {
|
||||
break;
|
||||
}
|
||||
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
|
||||
dynamic_cast<PhiInst *>(phiinst.get())->removeIncoming(basicblock.get());
|
||||
dynamic_cast<PhiInst *>(phiinst.get())->removeIncomingBlock(basicblock.get());
|
||||
}
|
||||
|
||||
} else { // cond为false或0
|
||||
@@ -665,7 +679,7 @@ bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder *pBuilder) {
|
||||
break;
|
||||
}
|
||||
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
|
||||
dynamic_cast<PhiInst *>(phiinst.get())->removeIncoming(basicblock.get());
|
||||
dynamic_cast<PhiInst *>(phiinst.get())->removeIncomingBlock(basicblock.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user