aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/Loads.cpp
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2019-12-10 14:41:30 -0800
committerHiroshi Yamauchi <yamauchi@google.com>2020-01-29 13:05:46 -0800
commit24962ced814123195be1a8cb41b615f255da824f (patch)
treeeac36d178a3c764d1cc587da0ea2d57e4859fe04 /llvm/lib/Analysis/Loads.cpp
parent00c2249910a17eee9c5a23bc82f2d2f5e1b6c867 (diff)
downloadllvm-24962ced814123195be1a8cb41b615f255da824f.zip
llvm-24962ced814123195be1a8cb41b615f255da824f.tar.gz
llvm-24962ced814123195be1a8cb41b615f255da824f.tar.bz2
[Loads] Handle simple cases with same base pointer with constant offsets in FindAvailableLoadedValue when AA is null.
Summary: This will help with devirtualization (store forwarding with vtable pointers in the presence of other stores into members in the constructor.) During inlining, we don't have AA. Reviewers: davidxl Subscribers: mgorny, Prazek, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71307
Diffstat (limited to 'llvm/lib/Analysis/Loads.cpp')
-rw-r--r--llvm/lib/Analysis/Loads.cpp41
1 files changed, 37 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 218fc3e..c2e9b8b 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -381,6 +381,28 @@ Value *llvm::FindAvailableLoadedValue(LoadInst *Load,
ScanFrom, MaxInstsToScan, AA, IsLoad, NumScanedInst);
}
+// Check if the load and the store have the same base, constant offsets and
+// non-overlapping access ranges.
+static bool AreNonOverlapSameBaseLoadAndStore(
+ Value *LoadPtr, Type *LoadTy, Value *StorePtr, Type *StoreTy,
+ const DataLayout &DL) {
+ APInt LoadOffset(DL.getTypeSizeInBits(LoadPtr->getType()), 0);
+ APInt StoreOffset(DL.getTypeSizeInBits(StorePtr->getType()), 0);
+ Value *LoadBase = LoadPtr->stripAndAccumulateConstantOffsets(
+ DL, LoadOffset, /* AllowNonInbounds */ false);
+ Value *StoreBase = StorePtr->stripAndAccumulateConstantOffsets(
+ DL, StoreOffset, /* AllowNonInbounds */ false);
+ if (LoadBase != StoreBase)
+ return false;
+ auto LoadAccessSize = LocationSize::precise(DL.getTypeStoreSize(LoadTy));
+ auto StoreAccessSize = LocationSize::precise(DL.getTypeStoreSize(StoreTy));
+ ConstantRange LoadRange(LoadOffset,
+ LoadOffset + LoadAccessSize.toRaw());
+ ConstantRange StoreRange(StoreOffset,
+ StoreOffset + StoreAccessSize.toRaw());
+ return LoadRange.intersectWith(StoreRange).isEmptySet();
+}
+
Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
bool AtLeastAtomic, BasicBlock *ScanBB,
BasicBlock::iterator &ScanFrom,
@@ -459,10 +481,21 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
StrippedPtr != StorePtr)
continue;
- // If we have alias analysis and it says the store won't modify the loaded
- // value, ignore the store.
- if (AA && !isModSet(AA->getModRefInfo(SI, StrippedPtr, AccessSize)))
- continue;
+ if (!AA) {
+ // When AA isn't available, but if the load and the store have the same
+ // base, constant offsets and non-overlapping access ranges, ignore the
+ // store. This is a simple form of alias analysis that is used by the
+ // inliner. FIXME: use BasicAA if possible.
+ if (AreNonOverlapSameBaseLoadAndStore(
+ Ptr, AccessTy, SI->getPointerOperand(),
+ SI->getValueOperand()->getType(), DL))
+ continue;
+ } else {
+ // If we have alias analysis and it says the store won't modify the
+ // loaded value, ignore the store.
+ if (!isModSet(AA->getModRefInfo(SI, StrippedPtr, AccessSize)))
+ continue;
+ }
// Otherwise the store that may or may not alias the pointer, bail out.
++ScanFrom;