llvm.org GIT mirror llvm / 93324fe
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275761 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 4 years ago
2 changed file(s) with 19 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
8080 }
8181 };
8282
83 // A map from a VN (value number) to all the instructions with that VN.
84 typedef DenseMap> VNtoInsns;
83 // A map from a pair of VNs to all the instructions with those VNs.
84 typedef DenseMap, SmallVector>
85 VNtoInsns;
86 // An invalid value number Used when inserting a single value number into
87 // VNtoInsns.
88 enum { InvalidVN = ~2U };
8589
8690 // Records all scalar instructions candidate for code hoisting.
8791 class InsnInfo {
9296 void insert(Instruction *I, GVN::ValueTable &VN) {
9397 // Scalar instruction.
9498 unsigned V = VN.lookupOrAdd(I);
95 VNtoScalars[V].push_back(I);
99 VNtoScalars[{V, InvalidVN}].push_back(I);
96100 }
97101
98102 const VNtoInsns &getVNTable() const { return VNtoScalars; }
107111 void insert(LoadInst *Load, GVN::ValueTable &VN) {
108112 if (Load->isSimple()) {
109113 unsigned V = VN.lookupOrAdd(Load->getPointerOperand());
110 VNtoLoads[V].push_back(Load);
114 VNtoLoads[{V, InvalidVN}].push_back(Load);
111115 }
112116 }
113117
127131 // Hash the store address and the stored value.
128132 Value *Ptr = Store->getPointerOperand();
129133 Value *Val = Store->getValueOperand();
130 VNtoStores[hash_combine(VN.lookupOrAdd(Ptr), VN.lookupOrAdd(Val))]
131 .push_back(Store);
134 VNtoStores[{VN.lookupOrAdd(Ptr), VN.lookupOrAdd(Val)}].push_back(Store);
132135 }
133136
134137 const VNtoInsns &getVNTable() const { return VNtoStores; }
147150 // onlyReadsMemory will be handled as a Load instruction,
148151 // all other calls will be handled as stores.
149152 unsigned V = VN.lookupOrAdd(Call);
153 auto Entry = std::make_pair(V, InvalidVN);
150154
151155 if (Call->doesNotAccessMemory())
152 VNtoCallsScalars[V].push_back(Call);
156 VNtoCallsScalars[Entry].push_back(Call);
153157 else if (Call->onlyReadsMemory())
154 VNtoCallsLoads[V].push_back(Call);
158 VNtoCallsLoads[Entry].push_back(Call);
155159 else
156 VNtoCallsStores[V].push_back(Call);
160 VNtoCallsStores[Entry].push_back(Call);
157161 }
158162
159163 const VNtoInsns &getScalarVNTable() const { return VNtoCallsScalars; }
77 ;
88 ; CHECK-LABEL: @scalarsHoisting
99 ; CHECK: fsub
10 ; CHECK: fmul
11 ; CHECK: fsub
10 ; CHECK: fsub
11 ; CHECK: fmul
1212 ; CHECK: fmul
1313 ; CHECK-NOT: fmul
1414 ; CHECK-NOT: fsub
4747 ; CHECK: load
4848 ; CHECK: load
4949 ; CHECK: fsub
50 ; CHECK: fmul
51 ; CHECK: fsub
50 ; CHECK: fsub
51 ; CHECK: fmul
5252 ; CHECK: fmul
5353 ; CHECK-NOT: load
5454 ; CHECK-NOT: fmul
222222
223223 ; Check that all independent expressions are hoisted.
224224 ; CHECK-LABEL: @independentScalarsHoisting
225 ; CHECK: fmul
226225 ; CHECK: fadd
226 ; CHECK: fsub
227227 ; CHECK: fdiv
228 ; CHECK: fsub
228 ; CHECK: fmul
229229 ; CHECK-NOT: fsub
230230 ; CHECK-NOT: fdiv
231231 ; CHECK-NOT: fmul