summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/SROA.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2019-07-09 11:35:35 +0000
committerTim Northover <tnorthover@apple.com>2019-07-09 11:35:35 +0000
commit60afa49abed6efdd7196d38ec884727090cfe373 (patch)
treea9af173067a23e1f6fa896cfb31bde34ec7cb3b3 /llvm/lib/Transforms/Scalar/SROA.cpp
parent01eaae6dd12862cda6b42d565a215b07a178aba6 (diff)
downloadbcm5719-llvm-60afa49abed6efdd7196d38ec884727090cfe373.tar.gz
bcm5719-llvm-60afa49abed6efdd7196d38ec884727090cfe373.zip
OpaquePtr: add Type parameter to Loads analysis API.
This makes the functions in Loads.h require a type to be specified independently of the pointer Value so that when pointers have no structure other than address-space, it can still do its job. Most callers had an obvious memory operation handy to provide this type, but a SROA and ArgumentPromotion were doing more complicated analysis. They get updated to merge the properties of the various instructions they were considering. llvm-svn: 365468
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SROA.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/SROA.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index cc79afdb05a..33f90d0b01e 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -1190,12 +1190,16 @@ static Type *findCommonType(AllocaSlices::const_iterator B,
/// FIXME: This should be hoisted into a generic utility, likely in
/// Transforms/Util/Local.h
static bool isSafePHIToSpeculate(PHINode &PN) {
+ const DataLayout &DL = PN.getModule()->getDataLayout();
+
// For now, we can only do this promotion if the load is in the same block
// as the PHI, and if there are no stores between the phi and load.
// TODO: Allow recursive phi users.
// TODO: Allow stores.
BasicBlock *BB = PN.getParent();
unsigned MaxAlign = 0;
+ uint64_t APWidth = DL.getIndexTypeSizeInBits(PN.getType());
+ APInt MaxSize(APWidth, 0);
bool HaveLoad = false;
for (User *U : PN.users()) {
LoadInst *LI = dyn_cast<LoadInst>(U);
@@ -1214,15 +1218,15 @@ static bool isSafePHIToSpeculate(PHINode &PN) {
if (BBI->mayWriteToMemory())
return false;
+ uint64_t Size = DL.getTypeStoreSizeInBits(LI->getType());
MaxAlign = std::max(MaxAlign, LI->getAlignment());
+ MaxSize = MaxSize.ult(Size) ? APInt(APWidth, Size) : MaxSize;
HaveLoad = true;
}
if (!HaveLoad)
return false;
- const DataLayout &DL = PN.getModule()->getDataLayout();
-
// We can only transform this if it is safe to push the loads into the
// predecessor blocks. The only thing to watch out for is that we can't put
// a possibly trapping load in the predecessor if it is a critical edge.
@@ -1244,7 +1248,7 @@ static bool isSafePHIToSpeculate(PHINode &PN) {
// If this pointer is always safe to load, or if we can prove that there
// is already a load in the block, then we can move the load to the pred
// block.
- if (isSafeToLoadUnconditionally(InVal, MaxAlign, DL, TI))
+ if (isSafeToLoadUnconditionally(InVal, MaxAlign, MaxSize, DL, TI))
continue;
return false;
@@ -1334,9 +1338,11 @@ static bool isSafeSelectToSpeculate(SelectInst &SI) {
// Both operands to the select need to be dereferenceable, either
// absolutely (e.g. allocas) or at this point because we can see other
// accesses to it.
- if (!isSafeToLoadUnconditionally(TValue, LI->getAlignment(), DL, LI))
+ if (!isSafeToLoadUnconditionally(TValue, LI->getType(), LI->getAlignment(),
+ DL, LI))
return false;
- if (!isSafeToLoadUnconditionally(FValue, LI->getAlignment(), DL, LI))
+ if (!isSafeToLoadUnconditionally(FValue, LI->getType(), LI->getAlignment(),
+ DL, LI))
return false;
}
OpenPOWER on IntegriCloud