Use hash table (key is a memory operand) to store found LEA instructions to reduce compile time.
Details
Diff Detail
Event Timeline
As Daniel suggested in https://llvm.org/bugs/show_bug.cgi?id=25843 I added a hash table to store LEAs to search for them faster in removeRedundantLEAs and removeRedundantAddrCalc.
I used the same test from the bug as in http://reviews.llvm.org/D15692, but with -Oz option (to enable the pass fully).
Here are the results:
Without LEA pass:
none$ time ./bin/clang++ -std=c++11 -S test-oz.ll -Oz -mllvm -disable-x86-lea-opt real 0m8.491s user 0m8.437s sys 0m0.052s
With old LEA pass:
none$ time ./bin/clang++ -std=c++11 -S test-oz.ll -Oz -mllvm -enable-x86-lea-opt real 0m8.878s user 0m8.819s sys 0m0.051s
With new LEA pass (no need to pass -enable-lea-opt any more):
none$ time ./bin/clang++ -std=c++11 -S test-oz.ll -Oz real 0m8.546s user 0m8.493s sys 0m0.051s
The difference for the current example is small, but visible. I think for the cases mentioned in the bug it will be more noticeable.
lib/Target/X86/X86OptimizeLEAs.cpp | ||
---|---|---|
42 | This change is unrelated and could be its own commit. | |
59 | You should use /// here. | |
83 | Explain in a comment why having two different immediate is still okay for operator==. | |
91 | Add comments for each field. | |
100 | This may be undefined behavior if size_t is a 32-bit value. | |
125 | We should have an assert on the kind of MI we get as input. | |
153 | Why not use a DenseMap? |
lib/Target/X86/X86OptimizeLEAs.cpp | ||
---|---|---|
100 | Or just use hash_code as the type :) | |
103 | You should just use hash_combine, which will call hash_value. IE hash_code Hash = hash_combine(*Key.Operands[0], *Key.Operands[1], *Key.Operands[2], *Key.Operands[3]); if (Key.Disp->isGlobal()) Hash = hash_combine(Hash, Key.Disp->getGlobal()); This will do all the mixing and calling of hash_value for you, and you won't need anything else in this function. |
lib/Target/X86/X86OptimizeLEAs.cpp | ||
---|---|---|
45 | Excluded from the patch. | |
59 | Done. | |
83 | Done. | |
91 | Done. | |
100 | I used hash_code inside the function and converted it into unsigned int since that's the return type expected from getHashValue. | |
103 | Fixed. | |
125 | assert((isLEA(MI) || MI.mayLoadOrStore()) && "The instruction must be a LEA, a load or a store"); Is that OK? | |
153 | Fixed. |
It looks like all the comments I had were fixed. Just ping quentin and make sure he's okay with it, and then LGTM.
(If we end up with further perf issues, we can look into changing it a bit more, but i'm pretty sure it's not going to take a lot of time at this point)
This change is unrelated and could be its own commit.