diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-05 19:13:42 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-05 19:13:42 +0000 |
commit | 57cbdfc99a4f19570841ff6dc89eae5f2b9c95cd (patch) | |
tree | 465df34cc920cede0fc399ed576523e23b94640f /llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp | |
parent | 3a078aefb63d71945efe58b0627ccc25a936a154 (diff) | |
download | bcm5719-llvm-57cbdfc99a4f19570841ff6dc89eae5f2b9c95cd.tar.gz bcm5719-llvm-57cbdfc99a4f19570841ff6dc89eae5f2b9c95cd.zip |
BFI: Saturate when combining edges to a successor
When a loop gets bundled up, its outgoing edges are quite large, and can
just barely overflow 64-bits. If one successor has multiple incoming
edges -- and that successor is getting all the incoming mass --
combining just its edges can overflow. Handle that by saturating rather
than asserting.
This fixes PR21622.
llvm-svn: 223500
Diffstat (limited to 'llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp')
-rw-r--r-- | llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp index 06b8acd9c75..278073cd6c5 100644 --- a/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp +++ b/llvm/lib/Analysis/BlockFrequencyInfoImpl.cpp @@ -14,6 +14,7 @@ #include "llvm/Analysis/BlockFrequencyInfoImpl.h" #include "llvm/ADT/SCCIterator.h" #include "llvm/Support/raw_ostream.h" +#include <numeric> using namespace llvm; using namespace llvm::bfi_detail; @@ -122,8 +123,12 @@ static void combineWeight(Weight &W, const Weight &OtherW) { } assert(W.Type == OtherW.Type); assert(W.TargetNode == OtherW.TargetNode); - assert(W.Amount < W.Amount + OtherW.Amount && "Unexpected overflow"); - W.Amount += OtherW.Amount; + assert(OtherW.Amount && "Expected non-zero weight"); + if (W.Amount > W.Amount + OtherW.Amount) + // Saturate on overflow. + W.Amount = UINT64_MAX; + else + W.Amount += OtherW.Amount; } static void combineWeightsBySorting(WeightList &Weights) { // Sort so edges to the same node are adjacent. @@ -206,11 +211,19 @@ void Distribution::normalize() { Shift = 33 - countLeadingZeros(Total); // Early exit if nothing needs to be scaled. - if (!Shift) + if (!Shift) { + // If we didn't overflow then combineWeights() shouldn't have changed the + // sum of the weights, but let's double-check. + assert(Total == std::accumulate(Weights.begin(), Weights.end(), UINT64_C(0), + [](uint64_t Sum, const Weight &W) { + return Sum + W.Amount; + }) && + "Expected total to be correct"); return; + } // Recompute the total through accumulation (rather than shifting it) so that - // it's accurate after shifting. + // it's accurate after shifting and any changes combineWeights() made above. Total = 0; // Sum the weights to each node and shift right if necessary. |