summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2018-08-29 21:49:30 +0000
committerPhilip Reames <listmail@philipreames.com>2018-08-29 21:49:30 +0000
commitf562fc8dbf279cf9c3ce2579d310c4afc448308a (patch)
tree1de5b869995e11571efe8534ea042eb00b132989 /llvm/lib/Analysis
parentfd48b7d5586189173f3d45d0b98952ab59d301cd (diff)
downloadbcm5719-llvm-f562fc8dbf279cf9c3ce2579d310c4afc448308a.tar.gz
bcm5719-llvm-f562fc8dbf279cf9c3ce2579d310c4afc448308a.zip
[LICM] Hoist stores of invariant values to invariant addresses out of loops
Teach LICM to hoist stores out of loops when the store writes to a location otherwise unused in the loop, writes a value which is invariant, and is guaranteed to execute if the loop is entered. Worth noting is that this transformation is partially overlapping with the existing promotion transformation. Reasons this is worthwhile anyway include: * For multi-exit loops, this doesn't require duplication of the store. * It kicks in for case where we can't prove we exit through a normal exit (i.e. we may throw), but can prove the store executes before that possible side exit. Differential Revision: https://reviews.llvm.org/D50925 llvm-svn: 340974
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/AliasSetTracker.cpp19
1 files changed, 16 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp
index 377db8a569f..51a61e9e2d9 100644
--- a/llvm/lib/Analysis/AliasSetTracker.cpp
+++ b/llvm/lib/Analysis/AliasSetTracker.cpp
@@ -256,9 +256,22 @@ Instruction* AliasSet::getUniqueInstruction() {
if (AliasAny)
// May have collapses alias set
return nullptr;
- if (size() != 0)
- // Can't track source of pointer, might be many instruction
- return nullptr;
+ if (begin() != end()) {
+ if (!UnknownInsts.empty())
+ // Another instruction found
+ return nullptr;
+ if (std::next(begin()) != end())
+ // Another instruction found
+ return nullptr;
+ Value *Addr = begin()->getValue();
+ assert(!Addr->user_empty() &&
+ "where's the instruction which added this pointer?");
+ if (std::next(Addr->user_begin()) != Addr->user_end())
+ // Another instruction found -- this is really restrictive
+ // TODO: generalize!
+ return nullptr;
+ return cast<Instruction>(*(Addr->user_begin()));
+ }
if (1 != UnknownInsts.size())
return nullptr;
return cast<Instruction>(UnknownInsts[0]);
OpenPOWER on IntegriCloud