summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2015-12-17 18:50:50 +0000
committerPhilip Reames <listmail@philipreames.com>2015-12-17 18:50:50 +0000
commit15145fb7b17d0499a706f8bb830dad272a06937d (patch)
treec9c45a31defa100b23fa82b04aaa58ae58cfd3d9 /llvm/lib
parent42c1e2923664d298970be6b0f8b21790859499e9 (diff)
downloadbcm5719-llvm-15145fb7b17d0499a706f8bb830dad272a06937d.tar.gz
bcm5719-llvm-15145fb7b17d0499a706f8bb830dad272a06937d.zip
[EarlyCSE] DSE of atomic unordered stores
The rules for removing trivially dead stores are a lot less complicated than loads. Since we know the later store post dominates the former and the former dominates the later, unless the former has side effects other than the actual store, we can remove it. One slightly surprising thing is that we can freely remove atomic stores, even if the later one isn't atomic. There's no guarantee the atomic one was every visible. For the moment, we don't handle DSE of ordered atomic stores. We could extend the same chain of reasoning to them, but the catch is we'd then have to model the ordering effect without a store instruction. Since our fences are a stronger than our operation orderings, simple using a fence isn't an obvious win. This arguable calls for a refinement in our fence specification, but that's (much) later work. Differential Revision: http://reviews.llvm.org/D15352 llvm-svn: 255914
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/EarlyCSE.cpp35
1 files changed, 17 insertions, 18 deletions
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
index 03f8c05c9d3..7ef062e71ff 100644
--- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
+++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp
@@ -411,15 +411,6 @@ private:
if (IsTargetMemInst) return Info.WriteMem;
return isa<StoreInst>(Inst);
}
- bool isSimple() const {
- if (IsTargetMemInst) return Info.IsSimple;
- if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
- return LI->isSimple();
- } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
- return SI->isSimple();
- }
- return Inst->isAtomic();
- }
bool isAtomic() const {
if (IsTargetMemInst) {
assert(Info.IsSimple && "need to refine IsSimple in TTI");
@@ -722,12 +713,17 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
if (MemInst.isValid() && MemInst.isStore()) {
// We do a trivial form of DSE if there are two stores to the same
- // location with no intervening loads. Delete the earlier store. Note
- // that we can delete an earlier simple store even if the following one
- // is ordered/volatile/atomic store.
+ // location with no intervening loads. Delete the earlier store.
+ // At the moment, we don't remove ordered stores, but do remove
+ // unordered atomic stores. There's no special requirement (for
+ // unordered atomics) about removing atomic stores only in favor of
+ // other atomic stores since we we're going to execute the non-atomic
+ // one anyway and the atomic one might never have become visible.
if (LastStore) {
ParseMemoryInst LastStoreMemInst(LastStore, TTI);
- assert(LastStoreMemInst.isSimple() && "Violated invariant");
+ assert(LastStoreMemInst.isUnordered() &&
+ !LastStoreMemInst.isVolatile() &&
+ "Violated invariant");
if (LastStoreMemInst.isMatchingMemLoc(MemInst)) {
DEBUG(dbgs() << "EarlyCSE DEAD STORE: " << *LastStore
<< " due to: " << *Inst << '\n');
@@ -749,11 +745,14 @@ bool EarlyCSE::processNode(DomTreeNode *Node) {
LoadValue(Inst, CurrentGeneration, MemInst.getMatchingId(),
MemInst.isAtomic()));
- // Remember that this was the last normal store we saw for DSE.
- // Note that we can't delete an earlier atomic or volatile store in
- // favor of a later one which isn't. We could in principle remove an
- // earlier unordered store if the later one is also unordered.
- if (MemInst.isSimple())
+ // Remember that this was the last unordered store we saw for DSE. We
+ // don't yet handle DSE on ordered or volatile stores since we don't
+ // have a good way to model the ordering requirement for following
+ // passes once the store is removed. We could insert a fence, but
+ // since fences are slightly stronger than stores in their ordering,
+ // it's not clear this is a profitable transform. Another option would
+ // be to merge the ordering with that of the post dominating store.
+ if (MemInst.isUnordered() && !MemInst.isVolatile())
LastStore = Inst;
else
LastStore = nullptr;
OpenPOWER on IntegriCloud