diff options
author | Philip Reames <listmail@philipreames.com> | 2016-03-25 22:40:35 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2016-03-25 22:40:35 +0000 |
commit | b5681138e41ea0c2712c6bf1b770f66391f45216 (patch) | |
tree | fd7751f7ef543b21296c78666ce3a88cccce10b0 /llvm/lib | |
parent | 0e32c5283ae8307179da18ddeef112435bbcbf6b (diff) | |
download | bcm5719-llvm-b5681138e41ea0c2712c6bf1b770f66391f45216.tar.gz bcm5719-llvm-b5681138e41ea0c2712c6bf1b770f66391f45216.zip |
Allow value forwarding past release fences in GVN
A release fence acts as a publication barrier for stores within the current thread to become visible to other threads which might observe the release fence. It does not require the current thread to observe stores performed on other threads. As a result, we can allow store-load and load-load forwarding across a release fence.
We choose to be much more conservative about stores. In theory, nothing prevents us from shifting a store from after a release fence to before it, and then eliminating the preceeding (previously fenced) store. Doing this without actually moving the second store is likely also legal, but we chose to be conservative at this time.
The LangRef indicates only atomic loads and stores are effected by fences. This patch chooses to be far more conservative then that.
This is the GVN companion to http://reviews.llvm.org/D11434 which applied the same logic in EarlyCSE and has been baking in tree for a while now.
Differential Revision: http://reviews.llvm.org/D11436
llvm-svn: 264472
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index 0890489c557..2436543a816 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -638,6 +638,15 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom( if (isInvariantLoad) continue; + // A release fence requires that all stores complete before it, but does + // not prevent the reordering of following loads or stores 'before' the + // fence. As a result, we look past it when finding a dependency for + // loads. DSE uses this to find preceeding stores to delete and thus we + // can't bypass the fence if the query instruction is a store. + if (FenceInst *FI = dyn_cast<FenceInst>(Inst)) + if (isLoad && FI->getOrdering() == Release) + continue; + // See if this instruction (e.g. a call or vaarg) mod/ref's the pointer. ModRefInfo MR = AA.getModRefInfo(Inst, MemLoc); // If necessary, perform additional analysis. |