diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-07-18 06:11:37 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-07-18 06:11:37 +0000 |
| commit | 04c7c225a12e5857ad01dac3c1d63fb256c4b07c (patch) | |
| tree | eab679d9c6c18ca888c2ad486a6f1baa0980b217 /llvm/lib/Transforms | |
| parent | 16be8ee1fff9793becfde9d9815b257aadce1ca3 (diff) | |
| download | bcm5719-llvm-04c7c225a12e5857ad01dac3c1d63fb256c4b07c.tar.gz bcm5719-llvm-04c7c225a12e5857ad01dac3c1d63fb256c4b07c.zip | |
[GVNHoist] Change the key for VNtoInsns to a pair
While debugging GVNHoist, I found it confusing that the entries in a
VNtoInsns were not always value numbers. They _usually_ were except for
StoreInst in which case they were a hash of two different value numbers.
This leads to two observations:
- It is more difficult to debug things when the semantic contents of
VNtoInsns changes over time.
- Using a single value number is not much cheaper, the value of
VNtoInsns is a SmallVector.
- It is not immediately clear what the algorithm would do if there were
hash collisions in the StoreInst case.
Using a DenseMap of std::pair sidesteps all of this.
N.B. The changes in the test were due their sensitivity to the
iteration order of VNtoInsns which has changed.
llvm-svn: 275761
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/GVNHoist.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVNHoist.cpp b/llvm/lib/Transforms/Scalar/GVNHoist.cpp index 57f27731e1c..92157df31bd 100644 --- a/llvm/lib/Transforms/Scalar/GVNHoist.cpp +++ b/llvm/lib/Transforms/Scalar/GVNHoist.cpp @@ -81,8 +81,12 @@ public: } }; -// A map from a VN (value number) to all the instructions with that VN. -typedef DenseMap<unsigned, SmallVector<Instruction *, 4>> VNtoInsns; +// A map from a pair of VNs to all the instructions with those VNs. +typedef DenseMap<std::pair<unsigned, unsigned>, SmallVector<Instruction *, 4>> + VNtoInsns; +// An invalid value number Used when inserting a single value number into +// VNtoInsns. +enum { InvalidVN = ~2U }; // Records all scalar instructions candidate for code hoisting. class InsnInfo { @@ -93,7 +97,7 @@ public: void insert(Instruction *I, GVN::ValueTable &VN) { // Scalar instruction. unsigned V = VN.lookupOrAdd(I); - VNtoScalars[V].push_back(I); + VNtoScalars[{V, InvalidVN}].push_back(I); } const VNtoInsns &getVNTable() const { return VNtoScalars; } @@ -108,7 +112,7 @@ public: void insert(LoadInst *Load, GVN::ValueTable &VN) { if (Load->isSimple()) { unsigned V = VN.lookupOrAdd(Load->getPointerOperand()); - VNtoLoads[V].push_back(Load); + VNtoLoads[{V, InvalidVN}].push_back(Load); } } @@ -128,8 +132,7 @@ public: // Hash the store address and the stored value. Value *Ptr = Store->getPointerOperand(); Value *Val = Store->getValueOperand(); - VNtoStores[hash_combine(VN.lookupOrAdd(Ptr), VN.lookupOrAdd(Val))] - .push_back(Store); + VNtoStores[{VN.lookupOrAdd(Ptr), VN.lookupOrAdd(Val)}].push_back(Store); } const VNtoInsns &getVNTable() const { return VNtoStores; } @@ -148,13 +151,14 @@ public: // onlyReadsMemory will be handled as a Load instruction, // all other calls will be handled as stores. unsigned V = VN.lookupOrAdd(Call); + auto Entry = std::make_pair(V, InvalidVN); if (Call->doesNotAccessMemory()) - VNtoCallsScalars[V].push_back(Call); + VNtoCallsScalars[Entry].push_back(Call); else if (Call->onlyReadsMemory()) - VNtoCallsLoads[V].push_back(Call); + VNtoCallsLoads[Entry].push_back(Call); else - VNtoCallsStores[V].push_back(Call); + VNtoCallsStores[Entry].push_back(Call); } const VNtoInsns &getScalarVNTable() const { return VNtoCallsScalars; } |

