[DeadStoreElimination] Refactor out pushMemUses, drop dead check (NFC)

This commit is contained in:
Antonio Frighetto
2024-07-11 21:43:04 +02:00
parent c9680bcdc5
commit d5c89cc811

View File

@@ -902,6 +902,16 @@ struct DSEState {
});
}
static void pushMemUses(MemoryAccess *Acc,
SmallVectorImpl<MemoryAccess *> &WorkList,
SmallPtrSetImpl<MemoryAccess *> &Visited) {
for (Use &U : Acc->uses()) {
auto *MA = cast<MemoryAccess>(U.getUser());
if (Visited.insert(MA).second)
WorkList.push_back(MA);
}
};
LocationSize strengthenLocationSize(const Instruction *I,
LocationSize Size) const {
if (auto *CB = dyn_cast<CallBase>(I)) {
@@ -1157,26 +1167,14 @@ struct DSEState {
}
/// Returns true if \p Def is not read before returning from the function.
bool isWriteAtEndOfFunction(MemoryDef *Def) {
bool isWriteAtEndOfFunction(MemoryDef *Def, const MemoryLocation &DefLoc) {
LLVM_DEBUG(dbgs() << " Check if def " << *Def << " ("
<< *Def->getMemoryInst()
<< ") is at the end the function \n");
auto MaybeLoc = getLocForWrite(Def->getMemoryInst());
if (!MaybeLoc) {
LLVM_DEBUG(dbgs() << " ... could not get location for write.\n");
return false;
}
SmallVector<MemoryAccess *, 4> WorkList;
SmallPtrSet<MemoryAccess *, 8> Visited;
auto PushMemUses = [&WorkList, &Visited](MemoryAccess *Acc) {
if (!Visited.insert(Acc).second)
return;
for (Use &U : Acc->uses())
WorkList.push_back(cast<MemoryAccess>(U.getUser()));
};
PushMemUses(Def);
pushMemUses(Def, WorkList, Visited);
for (unsigned I = 0; I < WorkList.size(); I++) {
if (WorkList.size() >= MemorySSAScanLimit) {
LLVM_DEBUG(dbgs() << " ... hit exploration limit.\n");
@@ -1188,22 +1186,22 @@ struct DSEState {
// AliasAnalysis does not account for loops. Limit elimination to
// candidates for which we can guarantee they always store to the same
// memory location.
if (!isGuaranteedLoopInvariant(MaybeLoc->Ptr))
if (!isGuaranteedLoopInvariant(DefLoc.Ptr))
return false;
PushMemUses(cast<MemoryPhi>(UseAccess));
pushMemUses(cast<MemoryPhi>(UseAccess), WorkList, Visited);
continue;
}
// TODO: Checking for aliasing is expensive. Consider reducing the amount
// of times this is called and/or caching it.
Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst();
if (isReadClobber(*MaybeLoc, UseInst)) {
if (isReadClobber(DefLoc, UseInst)) {
LLVM_DEBUG(dbgs() << " ... hit read clobber " << *UseInst << ".\n");
return false;
}
if (MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess))
PushMemUses(UseDef);
pushMemUses(UseDef, WorkList, Visited);
}
return true;
}
@@ -1505,12 +1503,9 @@ struct DSEState {
LLVM_DEBUG(dbgs() << " Checking for reads of " << *MaybeDeadAccess << " ("
<< *MaybeDeadI << ")\n");
SmallSetVector<MemoryAccess *, 32> WorkList;
auto PushMemUses = [&WorkList](MemoryAccess *Acc) {
for (Use &U : Acc->uses())
WorkList.insert(cast<MemoryAccess>(U.getUser()));
};
PushMemUses(MaybeDeadAccess);
SmallVector<MemoryAccess *, 32> WorkList;
SmallPtrSet<MemoryAccess *, 32> Visited;
pushMemUses(MaybeDeadAccess, WorkList, Visited);
// Check if DeadDef may be read.
for (unsigned I = 0; I < WorkList.size(); I++) {
@@ -1534,7 +1529,7 @@ struct DSEState {
continue;
}
LLVM_DEBUG(dbgs() << "\n ... adding PHI uses\n");
PushMemUses(UseAccess);
pushMemUses(UseAccess, WorkList, Visited);
continue;
}
@@ -1559,7 +1554,7 @@ struct DSEState {
if (isNoopIntrinsic(cast<MemoryUseOrDef>(UseAccess)->getMemoryInst())) {
LLVM_DEBUG(dbgs() << " ... adding uses of intrinsic\n");
PushMemUses(UseAccess);
pushMemUses(UseAccess, WorkList, Visited);
continue;
}
@@ -1618,7 +1613,7 @@ struct DSEState {
return std::nullopt;
}
} else
PushMemUses(UseDef);
pushMemUses(UseDef, WorkList, Visited);
}
}
@@ -1821,8 +1816,11 @@ struct DSEState {
Instruction *DefI = Def->getMemoryInst();
auto DefLoc = getLocForWrite(DefI);
if (!DefLoc || !isRemovable(DefI))
if (!DefLoc || !isRemovable(DefI)) {
LLVM_DEBUG(dbgs() << " ... could not get location for write or "
"instruction not removable.\n");
continue;
}
// NOTE: Currently eliminating writes at the end of a function is
// limited to MemoryDefs with a single underlying object, to save
@@ -1833,7 +1831,7 @@ struct DSEState {
if (!isInvisibleToCallerAfterRet(UO))
continue;
if (isWriteAtEndOfFunction(Def)) {
if (isWriteAtEndOfFunction(Def, *DefLoc)) {
// See through pointer-to-pointer bitcasts
LLVM_DEBUG(dbgs() << " ... MemoryDef is not accessed until the end "
"of the function\n");