diff options
author | Philip Reames <listmail@philipreames.com> | 2018-03-15 17:29:32 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2018-03-15 17:29:32 +0000 |
commit | ca587fe0b4749b5ffca8cfc8358ea4602e435bb7 (patch) | |
tree | 241736b9b956b7c7a9dfaab6df9bfae2c0126040 /llvm/lib/Transforms/Scalar/EarlyCSE.cpp | |
parent | 8e53917a26ad7504dfd6b1c956100c6b43433125 (diff) | |
download | bcm5719-llvm-ca587fe0b4749b5ffca8cfc8358ea4602e435bb7.tar.gz bcm5719-llvm-ca587fe0b4749b5ffca8cfc8358ea4602e435bb7.zip |
[EarlyCSE] Reuse invariant scopes for invariant load
This is a follow up to https://reviews.llvm.org/D43716 which rewrites the invariant load handling using the new infrastructure. It's slightly more powerful, but only in somewhat minor ways for the moment. It's not clear that DSE of stores to invariant locations is actually interesting since why would your IR have such a construct to start with?
Note: The submitted version is slightly different than the reviewed one. I realized the scope could start for an invariant load which was proven redundant and removed. Added a test case to illustrate that as well.
Differential Revision: https://reviews.llvm.org/D44497
llvm-svn: 327646
Diffstat (limited to 'llvm/lib/Transforms/Scalar/EarlyCSE.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/EarlyCSE.cpp | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp index a3ac0b59467..3f70ee49ad9 100644 --- a/llvm/lib/Transforms/Scalar/EarlyCSE.cpp +++ b/llvm/lib/Transforms/Scalar/EarlyCSE.cpp @@ -357,15 +357,11 @@ public: int MatchingId = -1; bool IsAtomic = false; - // TODO: Remove this flag. It would be strictly stronger to add a record - // to the AvailableInvariant table when passing the invariant load instead. - bool IsInvariant = false; - LoadValue() = default; LoadValue(Instruction *Inst, unsigned Generation, unsigned MatchingId, - bool IsAtomic, bool IsInvariant) + bool IsAtomic) : DefInst(Inst), Generation(Generation), MatchingId(MatchingId), - IsAtomic(IsAtomic), IsInvariant(IsInvariant) {} + IsAtomic(IsAtomic) {} }; using LoadMapAllocator = @@ -889,6 +885,14 @@ bool EarlyCSE::processNode(DomTreeNode *Node) { ++CurrentGeneration; } + if (MemInst.isInvariantLoad()) { + // If we pass an invariant load, we know that memory location is + // indefinitely constant from the moment of first dereferenceability. + // We conservatively treat the invariant_load as that moment. + auto MemLoc = MemoryLocation::get(Inst); + AvailableInvariants.insert(MemLoc, CurrentGeneration); + } + // If we have an available version of this load, and if it is the right // generation or the load is known to be from an invariant location, // replace this instruction. @@ -903,8 +907,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) { !MemInst.isVolatile() && MemInst.isUnordered() && // We can't replace an atomic load with one which isn't also atomic. InVal.IsAtomic >= MemInst.isAtomic() && - (InVal.IsInvariant || - isOperatingOnInvariantMemAt(Inst, InVal.Generation) || + (isOperatingOnInvariantMemAt(Inst, InVal.Generation) || isSameMemGeneration(InVal.Generation, CurrentGeneration, InVal.DefInst, Inst))) { Value *Op = getOrCreateResult(InVal.DefInst, Inst->getType()); @@ -925,7 +928,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) { AvailableLoads.insert( MemInst.getPointerOperand(), LoadValue(Inst, CurrentGeneration, MemInst.getMatchingId(), - MemInst.isAtomic(), MemInst.isInvariantLoad())); + MemInst.isAtomic())); LastStore = nullptr; continue; } @@ -1050,7 +1053,7 @@ bool EarlyCSE::processNode(DomTreeNode *Node) { AvailableLoads.insert( MemInst.getPointerOperand(), LoadValue(Inst, CurrentGeneration, MemInst.getMatchingId(), - MemInst.isAtomic(), /*IsInvariant=*/false)); + MemInst.isAtomic())); // 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 |