Go to file
Quentin Colombet b926bdac4c Reapply r263460: [SpillPlacement] Fix a quadratic behavior in spill placement.
Using Chandler's words from r265331:
This commit was greatly exacerbating PR17409 and effectively regressed
build time for lot of (very large) code when compiled with ASan or MSan.

PR17409 is fixed by r269249, so this is fine to reapply r263460.

Original commit message:
The bad behavior happens when we have a function with a long linear
chain of basic blocks, and have a live range spanning most of this
chain, but with very few uses.

Let say we have only 2 uses.

The Hopfield network is only seeded with two active blocks where the
uses are, and each iteration of the outer loop in
`RAGreedy::growRegion()` only adds two new nodes to the network due to
the completely linear shape of the CFG.  Meanwhile,
`SpillPlacer->iterate()` visits the whole set of discovered nodes, which
adds up to a quadratic algorithm.

This is an historical accident effect from r129188.

When the Hopfield network is expanding, most of the action is happening
on the frontier where new nodes are being added. The internal nodes in
the network are not likely to be flip-flopping much, or they will at
least settle down very quickly. This means that while
`SpillPlacer->iterate()` is recomputing all the nodes in the network, it
is probably only the two frontier nodes that are changing their output.

Instead of recomputing the whole network on each iteration, we can
maintain a SparseSet of nodes that need to be updated:

- `SpillPlacement::activate()` adds the node to the todo list.
- When a node changes value (i.e., `update()` returns true), its
  neighbors are added to the todo list.
- `SpillPlacement::iterate()` only updates the nodes in the list.

The result of Hopfield iterations is not necessarily exact. It should
converge to a local minimum, but there is no guarantee that it will find
a global minimum. It is possible that updating nodes in a different
order will cause us to switch to a different local minimum. In other
words, this is not NFC, but although I saw a few runtime improvements
and regressions when I benchmarked this change, those were side effects
and actually the performance change is in the noise as expected.

Huge thanks to Jakob Stoklund Olesen <stoklund@2pi.dk> for his
feedbacks, guidance and time for the review.

llvm-svn: 270149
2016-05-19 22:40:37 +00:00
clang [Sema] Fix use after move. Found by ubsan. 2016-05-19 21:53:33 +00:00
clang-tools-extra [include-fixer] Fix unused variable warning in Release builds. 2016-05-19 16:57:57 +00:00
compiler-rt [profile] entry eviction support in value profiler 2016-05-19 21:35:34 +00:00
debuginfo-tests New round of fixes for "Always compile debuginfo-tests for the host triple" 2014-10-18 23:47:59 +00:00
libclc math: Use single precision fmax in sp path 2016-05-17 19:44:01 +00:00
libcxx Cleanup superfluous std:: qualifiers in <type_traits> 2016-05-18 23:09:24 +00:00
libcxxabi libc++abi: make __cxa_call_unexpected visible 2016-05-11 23:56:37 +00:00
libunwind unwind: remove last instance of -Wexpansion-to-defined 2016-04-26 01:11:29 +00:00
lld Fix the function to set the section VMA/LMA fields in case of using 2016-05-19 18:15:54 +00:00
lldb Remove a should have been deleted extra assignment to a variable. 2016-05-19 22:22:57 +00:00
llgo [llgo] llgoi: separate evaluation from printing 2016-04-25 01:18:20 +00:00
llvm Reapply r263460: [SpillPlacement] Fix a quadratic behavior in spill placement. 2016-05-19 22:40:37 +00:00
openmp Remove unnecessary unistd.h header from tests. 2016-05-18 21:36:34 +00:00
polly Revert "Optimistic assume required invariant loads to be invariant" 2016-05-19 13:47:34 +00:00