[MemoryLocation] Move DSE's logic to new MemLoc::getForDest helper (NFC).

DSE has some extra logic to determine the write location of library
calls like str*cpy and str*cat. This patch moves the logic to a new
MemoryLocation:getForDest variant, which takes a call and TLI.

This patch should be NFC, because no other places take advantage of the
new helper yet.

Suggested by @reames post-commit 7eec832def.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D114872
This commit is contained in:
Florian Hahn 2021-12-03 09:12:01 +00:00
parent 49d040ac97
commit f078536f46
No known key found for this signature in database
GPG Key ID: EEF712BB5E80EBBA
3 changed files with 25 additions and 21 deletions

View File

@ -253,6 +253,8 @@ public:
static MemoryLocation getForDest(const MemIntrinsic *MI);
static MemoryLocation getForDest(const AtomicMemIntrinsic *MI);
static MemoryLocation getForDest(const AnyMemIntrinsic *MI);
static Optional<MemoryLocation> getForDest(const CallBase *CI,
const TargetLibraryInfo &TLI);
/// Return a location representing a particular argument of a call.
static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx,

View File

@ -128,6 +128,27 @@ MemoryLocation MemoryLocation::getForDest(const AnyMemIntrinsic *MI) {
return MemoryLocation(MI->getRawDest(), Size, MI->getAAMetadata());
}
Optional<MemoryLocation>
MemoryLocation::getForDest(const CallBase *CB, const TargetLibraryInfo &TLI) {
if (auto *MemInst = dyn_cast<AnyMemIntrinsic>(CB))
return getForDest(MemInst);
LibFunc LF;
if (TLI.getLibFunc(*CB, LF) && TLI.has(LF)) {
switch (LF) {
case LibFunc_strncpy:
case LibFunc_strcpy:
case LibFunc_strcat:
case LibFunc_strncat:
return getForArgument(CB, 0, &TLI);
default:
break;
}
}
return {};
}
MemoryLocation MemoryLocation::getForArgument(const CallBase *Call,
unsigned ArgIdx,
const TargetLibraryInfo *TLI) {

View File

@ -1026,32 +1026,12 @@ struct DSEState {
if (!I->mayWriteToMemory())
return None;
if (auto *MTI = dyn_cast<AnyMemIntrinsic>(I))
return {MemoryLocation::getForDest(MTI)};
if (auto *CB = dyn_cast<CallBase>(I)) {
// If the functions may write to memory we do not know about, bail out.
if (!CB->onlyAccessesArgMemory() &&
!CB->onlyAccessesInaccessibleMemOrArgMem())
return None;
LibFunc LF;
if (TLI.getLibFunc(*CB, LF) && TLI.has(LF)) {
switch (LF) {
case LibFunc_strncpy:
if (const auto *Len = dyn_cast<ConstantInt>(CB->getArgOperand(2)))
return MemoryLocation(CB->getArgOperand(0),
LocationSize::precise(Len->getZExtValue()),
CB->getAAMetadata());
LLVM_FALLTHROUGH;
case LibFunc_strcpy:
case LibFunc_strcat:
case LibFunc_strncat:
return {MemoryLocation::getAfter(CB->getArgOperand(0))};
default:
break;
}
}
switch (CB->getIntrinsicID()) {
case Intrinsic::init_trampoline:
return {MemoryLocation::getAfter(CB->getArgOperand(0))};
@ -1060,7 +1040,8 @@ struct DSEState {
default:
break;
}
return None;
return MemoryLocation::getForDest(CB, TLI);
}
return MemoryLocation::getOrNone(I);