llvm/lib/Transforms/IPO
JF Bastien 51be368e3f Improve the determinism of MergeFunctions
Summary:

Merge functions previously relied on unsigned comparisons of pointer values to
order functions. This caused observable non-determinism in the compiler for
large bitcode programs. Basically, opt -mergefuncs program.bc | md5sum produces
different hashes when run repeatedly on the same machine. Differing output was
observed on three large bitcodes, but it was less frequent on the smallest file.
It is possible that this only manifests on the large inputs, hence remaining
undetected until now.

This patch fixes this by removing (almost, see below) all places where
comparisons between pointers are used to order functions. Most of these changes
are local, but the comparison of global values requires assigning an identifier
to each local in the order it is visited. This is very similar to the way the
comparison function identifies Value*'s defined within a function. Because the
order of visiting the functions and their subparts is deterministic, the
identifiers assigned to the globals will be as well, and the order of functions
will be deterministic.

With these changes, there is no more observed non-determinism. There is also
only minor slowdowns (negligible to 4%) compared to the baseline, which is
likely a result of the fact that global comparisons involve hash lookups and not
just pointer comparisons.

The one caveat so far is that programs containing BlockAddress constants can
still be non-deterministic. It is not clear what the right solution is here. In
particular, even if the global numbers are used to order by function, we still
need a way to order the BasicBlock*'s. Unfortunately, we cannot just bail out
and fail to order the functions or consider them equal, because we require a
total order over functions. Note that programs with BlockAddress constants are
relatively rare, so the impact of leaving this in is minor as long as this pass
is opt-in.

Author: jrkoenig

Reviewers: nlewycky, jfb, dschuff

Subscribers: jevinskie, llvm-commits, chapuni

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245762 91177308-0d34-0410-b5e6-96231b3b80d8
2015-08-21 23:27:24 +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
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 [PM/AA] Remove the last relics of the separate IPA library from LLVM, 2015-08-18 17:51:53 +00:00
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 Improve the determinism of MergeFunctions 2015-08-21 23:27:24 +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