[midend-GVN]修复GVN中部分逻辑问题,LICM有bug待修复
This commit is contained in:
@@ -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<StoreInst*>(inst)) {
|
||||
invalidateLoadsAffectedByStore(storeInst);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
std::cout << " Visiting instruction: " << inst->getName()
|
||||
<< " (kind: " << static_cast<int>(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<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::ostringstream oss;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user