diff --git a/src/include/midend/Pass/Optimize/GVN.h b/src/include/midend/Pass/Optimize/GVN.h index ce11769..2aafd8d 100644 --- a/src/include/midend/Pass/Optimize/GVN.h +++ b/src/include/midend/Pass/Optimize/GVN.h @@ -59,6 +59,9 @@ private: // 检查两个load指令之间是否有store指令修改了相同的内存位置 bool hasInterveningStore(LoadInst* earlierLoad, LoadInst* laterLoad, Value* ptr); + // 使受store指令影响的load指令失效 + void invalidateLoadsAffectedByStore(StoreInst* storeInst); + // 生成表达式的标准化字符串 std::string getCanonicalExpression(Instruction* inst); }; diff --git a/src/midend/Pass/Optimize/GVN.cpp b/src/midend/Pass/Optimize/GVN.cpp index 76b0ffb..9f28609 100644 --- a/src/midend/Pass/Optimize/GVN.cpp +++ b/src/midend/Pass/Optimize/GVN.cpp @@ -301,8 +301,14 @@ Value *GVNContext::getValueNumber(LoadInst *inst) { if (ptr == loadPtr && inst->getType() == load->getType()) { // 检查两次load之间是否有store指令修改了内存 if (hasInterveningStore(load, inst, ptr)) { + if (DEBUG) { + std::cout << " Found intervening store, cannot reuse load value" << std::endl; + } continue; // 如果有store指令,不能复用之前的load } + if (DEBUG) { + std::cout << " No intervening store found, can reuse load value" << std::endl; + } return value; } } @@ -345,6 +351,11 @@ void GVNContext::visitInstruction(Instruction *inst) { return; } + // 如果是store指令,需要清理hashtable中可能被影响的load指令 + if (auto storeInst = dynamic_cast(inst)) { + invalidateLoadsAffectedByStore(storeInst); + } + if (DEBUG) { std::cout << " Visiting instruction: " << inst->getName() << " (kind: " << static_cast(inst->getKind()) << ")" << std::endl; @@ -490,6 +501,36 @@ bool GVNContext::hasInterveningStore(LoadInst* earlierLoad, LoadInst* laterLoad, 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 toRemove; + + for (auto& [key, value] : hashtable) { + if (auto loadInst = dynamic_cast(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::ostringstream oss; diff --git a/src/midend/Pass/Pass.cpp b/src/midend/Pass/Pass.cpp index 449508e..e5e6aab 100644 --- a/src/midend/Pass/Pass.cpp +++ b/src/midend/Pass/Pass.cpp @@ -132,7 +132,6 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR printPasses(); } - // 添加GVN优化遍 this->clearPasses(); this->addPass(&GVN::ID); this->run(); @@ -154,14 +153,14 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR this->clearPasses(); this->addPass(&LoopNormalizationPass::ID); this->addPass(&InductionVariableElimination::ID); - this->addPass(&LICM::ID); + // this->addPass(&LICM::ID); this->addPass(&LoopStrengthReduction::ID); this->run(); - if(DEBUG) { - std::cout << "=== IR After Loop Normalization, LICM, and Strength Reduction Optimizations ===\n"; - printPasses(); - } + // if(DEBUG) { + // std::cout << "=== IR After Loop Normalization, LICM, and Strength Reduction Optimizations ===\n"; + // printPasses(); + // } // this->clearPasses(); // this->addPass(&Reg2Mem::ID);