diff options
author | Philip Reames <listmail@philipreames.com> | 2018-08-29 21:49:30 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2018-08-29 21:49:30 +0000 |
commit | f562fc8dbf279cf9c3ce2579d310c4afc448308a (patch) | |
tree | 1de5b869995e11571efe8534ea042eb00b132989 /llvm/lib/Analysis | |
parent | fd48b7d5586189173f3d45d0b98952ab59d301cd (diff) | |
download | bcm5719-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.cpp | 19 |
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]); |