[midend-GVN]修复GVN中部分逻辑问题,LICM有bug待修复

This commit is contained in:
rain2133
2025-08-17 00:14:47 +08:00
parent c4eb1c3980
commit e32585fd25
3 changed files with 49 additions and 6 deletions

View File

@@ -59,6 +59,9 @@ private:
// 检查两个load指令之间是否有store指令修改了相同的内存位置 // 检查两个load指令之间是否有store指令修改了相同的内存位置
bool hasInterveningStore(LoadInst* earlierLoad, LoadInst* laterLoad, Value* ptr); bool hasInterveningStore(LoadInst* earlierLoad, LoadInst* laterLoad, Value* ptr);
// 使受store指令影响的load指令失效
void invalidateLoadsAffectedByStore(StoreInst* storeInst);
// 生成表达式的标准化字符串 // 生成表达式的标准化字符串
std::string getCanonicalExpression(Instruction* inst); std::string getCanonicalExpression(Instruction* inst);
}; };

View File

@@ -301,8 +301,14 @@ Value *GVNContext::getValueNumber(LoadInst *inst) {
if (ptr == loadPtr && inst->getType() == load->getType()) { if (ptr == loadPtr && inst->getType() == load->getType()) {
// 检查两次load之间是否有store指令修改了内存 // 检查两次load之间是否有store指令修改了内存
if (hasInterveningStore(load, inst, ptr)) { if (hasInterveningStore(load, inst, ptr)) {
if (DEBUG) {
std::cout << " Found intervening store, cannot reuse load value" << std::endl;
}
continue; // 如果有store指令不能复用之前的load continue; // 如果有store指令不能复用之前的load
} }
if (DEBUG) {
std::cout << " No intervening store found, can reuse load value" << std::endl;
}
return value; return value;
} }
} }
@@ -345,6 +351,11 @@ void GVNContext::visitInstruction(Instruction *inst) {
return; return;
} }
// 如果是store指令需要清理hashtable中可能被影响的load指令
if (auto storeInst = dynamic_cast<StoreInst*>(inst)) {
invalidateLoadsAffectedByStore(storeInst);
}
if (DEBUG) { if (DEBUG) {
std::cout << " Visiting instruction: " << inst->getName() std::cout << " Visiting instruction: " << inst->getName()
<< " (kind: " << static_cast<int>(inst->getKind()) << ")" << std::endl; << " (kind: " << static_cast<int>(inst->getKind()) << ")" << std::endl;
@@ -490,6 +501,36 @@ bool GVNContext::hasInterveningStore(LoadInst* earlierLoad, LoadInst* laterLoad,
return false; // 没有找到会修改内存的指令 return false; // 没有找到会修改内存的指令
} }
void GVNContext::invalidateLoadsAffectedByStore(StoreInst* storeInst) {
auto storePtr = checkHashtable(storeInst->getPointer());
if (DEBUG) {
std::cout << " Invalidating loads affected by store to address" << std::endl;
}
// 查找hashtable中所有可能被这个store影响的load指令
std::vector<Value*> toRemove;
for (auto& [key, value] : hashtable) {
if (auto loadInst = dynamic_cast<LoadInst*>(key)) {
auto loadPtr = checkHashtable(loadInst->getPointer());
// 如果load的地址与store的地址相同则需要从hashtable中移除
if (loadPtr == storePtr) {
toRemove.push_back(key);
if (DEBUG) {
std::cout << " Invalidating load from same address: " << loadInst->getName() << std::endl;
}
}
}
}
// 从hashtable中移除被影响的load指令
for (auto key : toRemove) {
hashtable.erase(key);
}
}
std::string GVNContext::getCanonicalExpression(Instruction *inst) { std::string GVNContext::getCanonicalExpression(Instruction *inst) {
std::ostringstream oss; std::ostringstream oss;

View File

@@ -132,7 +132,6 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
printPasses(); printPasses();
} }
// 添加GVN优化遍
this->clearPasses(); this->clearPasses();
this->addPass(&GVN::ID); this->addPass(&GVN::ID);
this->run(); this->run();
@@ -154,14 +153,14 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
this->clearPasses(); this->clearPasses();
this->addPass(&LoopNormalizationPass::ID); this->addPass(&LoopNormalizationPass::ID);
this->addPass(&InductionVariableElimination::ID); this->addPass(&InductionVariableElimination::ID);
this->addPass(&LICM::ID); // this->addPass(&LICM::ID);
this->addPass(&LoopStrengthReduction::ID); this->addPass(&LoopStrengthReduction::ID);
this->run(); this->run();
if(DEBUG) { // if(DEBUG) {
std::cout << "=== IR After Loop Normalization, LICM, and Strength Reduction Optimizations ===\n"; // std::cout << "=== IR After Loop Normalization, LICM, and Strength Reduction Optimizations ===\n";
printPasses(); // printPasses();
} // }
// this->clearPasses(); // this->clearPasses();
// this->addPass(&Reg2Mem::ID); // this->addPass(&Reg2Mem::ID);