[DeadStoreElimination] Refactor out pushMemUses, drop dead check (NFC)
This commit is contained in:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user