llvm/lib/Transforms/IPO
JF Bastien 6470102728 Accelerate MergeFunctions with hashing
This patch makes the Merge Functions pass faster by calculating and comparing
a hash value which captures the essential structure of a function before
performing a full function comparison.

The hash is calculated by hashing the function signature, then walking the basic
blocks of the function in the same order as the main comparison function. The
opcode of each instruction is hashed in sequence, which means that different
functions according to the existing total order cannot have the same hash, as
the comparison requires the opcodes of the two functions to be the same order.

The hash function is a static member of the FunctionComparator class because it
is tightly coupled to the exact comparison function used. For example, functions
which are equivalent modulo a single variant callsite might be merged by a more
aggressive MergeFunctions, and the hash function would need to be insensitive to
these differences in order to exploit this.

The hashing function uses a utility class which accumulates the values into an
internal state using a standard bit-mixing function. Note that this is a different interface
than a regular hashing routine, because the values to be hashed are scattered
amongst the properties of a llvm::Function, not linear in memory. This scheme is
fast because only one word of state needs to be kept, and the mixing function is
a few instructions.

The main runOnModule function first computes the hash of each function, and only
further processes functions which do not have a unique function hash. The hash
is also used to order the sorted function set. If the hashes differ, their
values are used to order the functions, otherwise the full comparison is done.

Both of these are helpful in speeding up MergeFunctions. Together they result in
speedups of 9% for mysqld (a mostly C application with little redundancy), 46%
for libxul in Firefox, and 117% for Chromium. (These are all LTO builds.) In all
three cases, the new speed of MergeFunctions is about half that of the module
verifier, making it relatively inexpensive even for large LTO builds with
hundreds of thousands of functions. The same functions are merged, so this
change is free performance.

Author: jrkoenig

Reviewers: nlewycky, dschuff, jfb

Subscribers: llvm-commits, aemerson

Differential revision: http://reviews.llvm.org/D11923

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245140 91177308-0d34-0410-b5e6-96231b3b80d8
2015-08-15 01:18:18 +00:00
..
ArgumentPromotion.cpp Use foreach loops for StructType::elements(). NFC. 2015-07-24 18:55:49 +00:00
BarrierNoopPass.cpp
CMakeLists.txt
ConstantMerge.cpp
DeadArgumentElimination.cpp
ElimAvailExtern.cpp Remove unused variable. 2015-07-13 14:43:33 +00:00
ExtractGV.cpp
FunctionAttrs.cpp Remove unused variable. NFC. 2015-07-24 19:18:32 +00:00
GlobalDCE.cpp Rangify for loops in GlobalDCE, NFC. 2015-07-18 19:57:34 +00:00
GlobalOpt.cpp Revert "Improve merging of stores from static constructors in GlobalOpt" 2015-07-22 22:26:54 +00:00
InlineAlways.cpp
Inliner.cpp Variable names should start with an upper case letter; NFC 2015-08-11 16:05:43 +00:00
InlineSimple.cpp
Internalize.cpp Internalize: internalize comdat members as a group, and drop comdat on such members. 2015-07-16 17:42:21 +00:00
IPConstantPropagation.cpp
IPO.cpp
LLVMBuild.txt
LoopExtractor.cpp Drive-by fixes for LandingPad -> EHPad 2015-08-04 08:21:40 +00:00
LowerBitSets.cpp LowerBitSets: Add debugging output. 2015-07-29 18:12:36 +00:00
Makefile
MergeFunctions.cpp Accelerate MergeFunctions with hashing 2015-08-15 01:18:18 +00:00
PartialInlining.cpp
PassManagerBuilder.cpp [PM/AA] Extract the interface for GlobalsModRef into a header along with 2015-08-14 03:48:20 +00:00
PruneEH.cpp
StripDeadPrototypes.cpp
StripSymbols.cpp