forked from OSchip/llvm-project
[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:
parent
49d040ac97
commit
f078536f46
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue