[midend-Alias]应用别名分析结果,sccp现在能简单传播数组元素了

This commit is contained in:
rain2133
2025-08-08 02:12:32 +08:00
parent b1a46b7d58
commit a406e44df3
7 changed files with 590 additions and 38 deletions

View File

@@ -251,6 +251,9 @@ void SysYAliasAnalysisPass::analyzeMemoryType(MemoryLocation* location) {
void SysYAliasAnalysisPass::analyzeIndexPattern(MemoryLocation* location) {
// 分析GEP指令的索引模式
if (auto* gepInst = dynamic_cast<GetElementPtrInst*>(location->accessPointer)) {
// 初始化为true如果发现非常量索引则设为false
location->hasConstantIndices = true;
// 收集所有索引
for (unsigned i = 0; i < gepInst->getNumIndices(); ++i) {
Value* index = gepInst->getIndex(i);
@@ -262,11 +265,6 @@ void SysYAliasAnalysisPass::analyzeIndexPattern(MemoryLocation* location) {
}
}
// 如果没有非常量索引,则为常量访问
if (location->indices.empty()) {
location->hasConstantIndices = true;
}
// 检查是否包含循环变量
Function* containingFunc = nullptr;
if (auto* inst = dynamic_cast<Instruction*>(location->basePointer)) {
@@ -289,9 +287,15 @@ void SysYAliasAnalysisPass::analyzeIndexPattern(MemoryLocation* location) {
AliasType SysYAliasAnalysisPass::analyzeAliasBetween(MemoryLocation* loc1, MemoryLocation* loc2) {
// 分析两个内存位置之间的别名关系
// 1. 相同基指针的自别名
// 1. 相同基指针的情况需要进一步分析索引
if (loc1->basePointer == loc2->basePointer) {
return AliasType::SELF_ALIAS;
// 如果是同一个访问指针,那就是完全相同的内存位置
if (loc1->accessPointer == loc2->accessPointer) {
return AliasType::SELF_ALIAS;
}
// 相同基指针但不同访问指针,需要比较索引
return compareIndices(loc1, loc2);
}
// 2. 不同类型的内存位置
@@ -310,6 +314,46 @@ AliasType SysYAliasAnalysisPass::analyzeAliasBetween(MemoryLocation* loc1, Memor
return compareMixedTypes(loc1, loc2);
}
AliasType SysYAliasAnalysisPass::compareIndices(MemoryLocation* loc1, MemoryLocation* loc2) {
// 比较相同基指针下的不同索引访问
// 如果都有常量索引,可以精确比较
if (loc1->hasConstantIndices && loc2->hasConstantIndices) {
// 比较索引数量
if (loc1->indices.size() != loc2->indices.size()) {
return AliasType::NO_ALIAS;
}
// 逐个比较索引值
for (size_t i = 0; i < loc1->indices.size(); ++i) {
Value* idx1 = loc1->indices[i];
Value* idx2 = loc2->indices[i];
// 都是常量,比较值
auto* const1 = dynamic_cast<ConstantInteger*>(idx1);
auto* const2 = dynamic_cast<ConstantInteger*>(idx2);
if (const1 && const2) {
int val1 = std::get<int>(const1->getVal());
int val2 = std::get<int>(const2->getVal());
if (val1 != val2) {
return AliasType::NO_ALIAS; // 不同常量索引,确定无别名
}
} else {
// 不是常量,无法确定
return AliasType::POSSIBLE_ALIAS;
}
}
// 所有索引都相同
return AliasType::SELF_ALIAS;
}
// 如果有非常量索引,保守估计
return AliasType::POSSIBLE_ALIAS;
}
AliasType SysYAliasAnalysisPass::compareLocalArrays(MemoryLocation* loc1, MemoryLocation* loc2) {
// 不同局部数组不别名
return AliasType::NO_ALIAS;