[midend-Loop-InductionVarStrengthReduction]支持了对部分除法运算取模运算的归纳变量的强度削弱策略。(mulh+魔数,负数2的幂次除法符号修正,2的幂次取模运算and优化)。增加了了Printer对移位指令的打印支持
This commit is contained in:
@@ -321,7 +321,7 @@ void LoopCharacteristicsPass::identifyBasicInductionVariables(
|
||||
auto* phi = dynamic_cast<PhiInst*>(inst.get());
|
||||
if (!phi) continue;
|
||||
if (isBasicInductionVariable(phi, loop)) {
|
||||
ivs.push_back(InductionVarInfo::createBasicBIV(phi, Instruction::Kind::kPhi));
|
||||
ivs.push_back(InductionVarInfo::createBasicBIV(phi, Instruction::Kind::kPhi, phi));
|
||||
if (DEBUG) {
|
||||
std::cout << " [BIV] Found basic induction variable: " << phi->getName() << std::endl;
|
||||
std::cout << " Incoming values: ";
|
||||
@@ -340,9 +340,23 @@ void LoopCharacteristicsPass::identifyBasicInductionVariables(
|
||||
// 2. 递归识别所有派生DIV
|
||||
std::set<Value*> visited;
|
||||
size_t initialSize = ivs.size();
|
||||
for (const auto& biv : ivs) {
|
||||
|
||||
// 保存初始的BIV列表,避免在遍历过程中修改向量导致迭代器失效
|
||||
std::vector<InductionVarInfo*> bivList;
|
||||
for (size_t i = 0; i < initialSize; ++i) {
|
||||
if (ivs[i] && ivs[i]->ivkind == IVKind::kBasic) {
|
||||
bivList.push_back(ivs[i].get());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* biv : bivList) {
|
||||
if (DEBUG) {
|
||||
std::cout << " Searching for derived IVs from BIV: " << biv->div->getName() << std::endl;
|
||||
if (biv && biv->div) {
|
||||
std::cout << " Searching for derived IVs from BIV: " << biv->div->getName() << std::endl;
|
||||
} else {
|
||||
std::cout << " ERROR: Invalid BIV pointer or div field is null" << std::endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
findDerivedInductionVars(biv->div, biv->base, loop, ivs, visited);
|
||||
}
|
||||
@@ -537,6 +551,58 @@ static LinearExpr analyzeLinearExpr(Value* val, Loop* loop, std::vector<std::uni
|
||||
std::cout << " -> Multiplication pattern not supported" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 除法:BIV/const(仅当const是2的幂时)
|
||||
if (kind == Instruction::Kind::kDiv) {
|
||||
if (DEBUG >= 2) {
|
||||
std::cout << " -> Analyzing division" << std::endl;
|
||||
}
|
||||
auto expr0 = analyzeLinearExpr(inst->getOperand(0), loop, ivs);
|
||||
auto expr1 = analyzeLinearExpr(inst->getOperand(1), loop, ivs);
|
||||
|
||||
// 只支持 BIV / 2^n 形式
|
||||
if (expr0.base1 && !expr1.base1 && !expr1.base2 && expr1.offset > 0) {
|
||||
// 检查是否为2的幂
|
||||
int divisor = expr1.offset;
|
||||
if ((divisor & (divisor - 1)) == 0) { // 2的幂检查
|
||||
if (DEBUG >= 2) {
|
||||
std::cout << " -> BIV / power_of_2 pattern (divisor=" << divisor << ")" << std::endl;
|
||||
}
|
||||
// 对于除法,我们记录为特殊的归纳变量模式
|
||||
// factor表示除数(用于后续强度削弱)
|
||||
return {expr0.base1, nullptr, -divisor, 0, expr0.offset / divisor, true, true};
|
||||
}
|
||||
}
|
||||
if (DEBUG >= 2) {
|
||||
std::cout << " -> Division pattern not supported (not power of 2)" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 取模:BIV % const(仅当const是2的幂时)
|
||||
if (kind == Instruction::Kind::kRem) {
|
||||
if (DEBUG >= 2) {
|
||||
std::cout << " -> Analyzing remainder" << std::endl;
|
||||
}
|
||||
auto expr0 = analyzeLinearExpr(inst->getOperand(0), loop, ivs);
|
||||
auto expr1 = analyzeLinearExpr(inst->getOperand(1), loop, ivs);
|
||||
|
||||
// 只支持 BIV % 2^n 形式
|
||||
if (expr0.base1 && !expr1.base1 && !expr1.base2 && expr1.offset > 0) {
|
||||
// 检查是否为2的幂
|
||||
int modulus = expr1.offset;
|
||||
if ((modulus & (modulus - 1)) == 0) { // 2的幂检查
|
||||
if (DEBUG >= 2) {
|
||||
std::cout << " -> BIV % power_of_2 pattern (modulus=" << modulus << ")" << std::endl;
|
||||
}
|
||||
// 对于取模,我们记录为特殊的归纳变量模式
|
||||
// 使用负的模数来区分取模和除法
|
||||
return {expr0.base1, nullptr, -10000 - modulus, 0, 0, true, true}; // 特殊标记
|
||||
}
|
||||
}
|
||||
if (DEBUG >= 2) {
|
||||
std::cout << " -> Remainder pattern not supported (not power of 2)" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 其它情况
|
||||
@@ -648,7 +714,7 @@ void LoopCharacteristicsPass::findDerivedInductionVars(
|
||||
<< " (kind: " << static_cast<int>(inst->getKind()) << ")" << std::endl;
|
||||
}
|
||||
|
||||
// 下面是一个例子:假设你有线性归约分析(可用analyzeLinearExpr等递归辅助)
|
||||
// 线性归约分析
|
||||
auto expr = analyzeLinearExpr(inst, loop, ivs);
|
||||
|
||||
if (!expr.valid) {
|
||||
@@ -669,14 +735,29 @@ void LoopCharacteristicsPass::findDerivedInductionVars(
|
||||
|
||||
// 单BIV线性
|
||||
if (expr.base1 && !expr.base2) {
|
||||
if (DEBUG) {
|
||||
std::cout << " [DIV-LINEAR] Creating single-base derived IV: " << inst->getName()
|
||||
<< " with base: " << expr.base1->getName()
|
||||
<< ", factor: " << expr.factor1
|
||||
<< ", offset: " << expr.offset << std::endl;
|
||||
// 检查这个指令是否已经是一个已知的IV(特别是BIV),避免重复创建
|
||||
bool alreadyExists = false;
|
||||
for (const auto& existingIV : ivs) {
|
||||
if (existingIV->div == inst) {
|
||||
alreadyExists = true;
|
||||
if (DEBUG) {
|
||||
std::cout << " [DIV-SKIP] Instruction " << inst->getName()
|
||||
<< " already exists as IV, skipping creation" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadyExists) {
|
||||
if (DEBUG) {
|
||||
std::cout << " [DIV-LINEAR] Creating single-base derived IV: " << inst->getName()
|
||||
<< " with base: " << expr.base1->getName()
|
||||
<< ", factor: " << expr.factor1
|
||||
<< ", offset: " << expr.offset << std::endl;
|
||||
}
|
||||
ivs.push_back(InductionVarInfo::createSingleDIV(inst, inst->getKind(), expr.base1, expr.factor1, expr.offset));
|
||||
findDerivedInductionVars(inst, expr.base1, loop, ivs, visited);
|
||||
}
|
||||
ivs.push_back(InductionVarInfo::createSingleDIV(inst, inst->getKind(), expr.base1, expr.factor1, expr.offset));
|
||||
findDerivedInductionVars(inst, expr.base1, loop, ivs, visited);
|
||||
}
|
||||
// 双BIV线性
|
||||
else if (expr.base1 && expr.base2) {
|
||||
|
||||
Reference in New Issue
Block a user