[midend-LICM]优化了特征分析中对循环不变量的识别,实现了LICM遍,格式化副作用分析代码
This commit is contained in:
@@ -303,26 +303,32 @@ void LoopCharacteristicsPass::identifyBasicInductionVariables(Loop* loop, LoopCh
|
||||
}
|
||||
|
||||
void LoopCharacteristicsPass::identifyBasicLoopInvariants(Loop* loop, LoopCharacteristics* characteristics) {
|
||||
// 收集基础循环不变量(简化版本)
|
||||
for (BasicBlock* bb : loop->getBlocks()) {
|
||||
for (auto& inst : bb->getInstructions()) {
|
||||
Value* val = inst.get();
|
||||
|
||||
// 跳过phi指令和终结指令
|
||||
if (dynamic_cast<PhiInst*>(val)) continue;
|
||||
if (auto* instPtr = dynamic_cast<Instruction*>(val)) {
|
||||
if (instPtr->isTerminator()) continue;
|
||||
}
|
||||
|
||||
if (isBasicLoopInvariant(val, loop)) {
|
||||
characteristics->loopInvariants.insert(val);
|
||||
characteristics->invariantInsts.insert(static_cast<Instruction*>(val));
|
||||
|
||||
if (DEBUG)
|
||||
std::cout << " Found basic loop invariant: " << val->getName() << std::endl;
|
||||
// 经典推进法:反复遍历,直到收敛
|
||||
bool changed;
|
||||
std::unordered_set<Value*> invariants = characteristics->loopInvariants; // 可能为空
|
||||
|
||||
do {
|
||||
changed = false;
|
||||
for (BasicBlock* bb : loop->getBlocks()) {
|
||||
for (auto& inst : bb->getInstructions()) {
|
||||
Instruction* I = inst.get();
|
||||
// 跳过phi和terminator
|
||||
if (dynamic_cast<PhiInst*>(I)) continue;
|
||||
if (I->isTerminator()) continue;
|
||||
if (invariants.count(I)) continue;
|
||||
|
||||
if (isClassicLoopInvariant(I, loop, invariants)) {
|
||||
invariants.insert(I);
|
||||
characteristics->invariantInsts.insert(I);
|
||||
if (DEBUG)
|
||||
std::cout << " Found loop invariant: " << I->getName() << std::endl;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (changed);
|
||||
|
||||
characteristics->loopInvariants = std::move(invariants);
|
||||
}
|
||||
|
||||
void LoopCharacteristicsPass::analyzeBasicLoopBounds(Loop* loop, LoopCharacteristics* characteristics) {
|
||||
@@ -385,22 +391,32 @@ bool LoopCharacteristicsPass::isBasicInductionVariable(Value* val, Loop* loop) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoopCharacteristicsPass::isBasicLoopInvariant(Value* val, Loop* loop) {
|
||||
auto* inst = dynamic_cast<Instruction*>(val);
|
||||
if (!inst) return true; // 非指令(如常量)认为是不变的
|
||||
|
||||
// 如果指令不在循环内定义,则是不变的
|
||||
if (!loop->contains(inst->getParent())) {
|
||||
// 递归/推进式判定
|
||||
bool LoopCharacteristicsPass::isClassicLoopInvariant(Value* val, Loop* loop, const std::unordered_set<Value*>& invariants) {
|
||||
// 1. 常量
|
||||
if (auto* constval = dynamic_cast<ConstantValue*>(val)) return true;
|
||||
|
||||
// 2. 参数(函数参数)通常不在任何BasicBlock内,直接判定为不变量
|
||||
if (auto* arg = dynamic_cast<Argument*>(val)) return true;
|
||||
|
||||
// 3. 指令且定义在循环外
|
||||
if (auto* inst = dynamic_cast<Instruction*>(val)) {
|
||||
if (!loop->contains(inst->getParent()))
|
||||
return true;
|
||||
|
||||
// 4. 跳转 phi指令 副作用 不外提
|
||||
if (inst->isTerminator() || inst->isPhi() || sideEffectAnalysis->hasSideEffect(inst))
|
||||
return false;
|
||||
|
||||
// 5. 所有操作数都是不变量
|
||||
for (size_t i = 0; i < inst->getNumOperands(); ++i) {
|
||||
Value* op = inst->getOperand(i);
|
||||
if (!isClassicLoopInvariant(op, loop, invariants) && !invariants.count(op))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 简化的基础不变量检测:load指令且指针是循环外的
|
||||
if (auto* loadInst = dynamic_cast<LoadInst*>(inst)) {
|
||||
Value* ptr = loadInst->getPointer();
|
||||
return isBasicLoopInvariant(ptr, loop);
|
||||
}
|
||||
|
||||
// 保守:对于其他指令,认为是变化的
|
||||
// 其它情况
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user