mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
Merging r223500 (this time for real):
------------------------------------------------------------------------ r223500 | dexonsmith | 2014-12-05 11:13:42 -0800 (Fri, 05 Dec 2014) | 9 lines 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. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@223716 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c2594296e6
commit
9696b167f2
@ -14,7 +14,7 @@
|
|||||||
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
|
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
|
||||||
#include "llvm/ADT/SCCIterator.h"
|
#include "llvm/ADT/SCCIterator.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <deque>
|
#include <numeric>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using namespace llvm::bfi_detail;
|
using namespace llvm::bfi_detail;
|
||||||
@ -123,8 +123,12 @@ static void combineWeight(Weight &W, const Weight &OtherW) {
|
|||||||
}
|
}
|
||||||
assert(W.Type == OtherW.Type);
|
assert(W.Type == OtherW.Type);
|
||||||
assert(W.TargetNode == OtherW.TargetNode);
|
assert(W.TargetNode == OtherW.TargetNode);
|
||||||
assert(W.Amount < W.Amount + OtherW.Amount && "Unexpected overflow");
|
assert(OtherW.Amount && "Expected non-zero weight");
|
||||||
W.Amount += OtherW.Amount;
|
if (W.Amount > W.Amount + OtherW.Amount)
|
||||||
|
// Saturate on overflow.
|
||||||
|
W.Amount = UINT64_MAX;
|
||||||
|
else
|
||||||
|
W.Amount += OtherW.Amount;
|
||||||
}
|
}
|
||||||
static void combineWeightsBySorting(WeightList &Weights) {
|
static void combineWeightsBySorting(WeightList &Weights) {
|
||||||
// Sort so edges to the same node are adjacent.
|
// Sort so edges to the same node are adjacent.
|
||||||
@ -207,11 +211,19 @@ void Distribution::normalize() {
|
|||||||
Shift = 33 - countLeadingZeros(Total);
|
Shift = 33 - countLeadingZeros(Total);
|
||||||
|
|
||||||
// Early exit if nothing needs to be scaled.
|
// 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Recompute the total through accumulation (rather than shifting it) so that
|
// 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;
|
Total = 0;
|
||||||
|
|
||||||
// Sum the weights to each node and shift right if necessary.
|
// Sum the weights to each node and shift right if necessary.
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
; RUN: opt < %s -analyze -block-freq | FileCheck %s
|
||||||
|
|
||||||
|
; PR21622: Check for a crasher when the sum of exits to the same successor of a
|
||||||
|
; loop overflows.
|
||||||
|
|
||||||
|
; CHECK-LABEL: Printing analysis {{.*}} for function 'extremely_likely_loop_successor':
|
||||||
|
; CHECK-NEXT: block-frequency-info: extremely_likely_loop_successor
|
||||||
|
define void @extremely_likely_loop_successor() {
|
||||||
|
; CHECK-NEXT: entry: float = 1.0, int = [[ENTRY:[0-9]+]]
|
||||||
|
entry:
|
||||||
|
br label %loop
|
||||||
|
|
||||||
|
; CHECK-NEXT: loop: float = 1.0,
|
||||||
|
loop:
|
||||||
|
%exit.1.cond = call i1 @foo()
|
||||||
|
br i1 %exit.1.cond, label %exit, label %loop.2, !prof !0
|
||||||
|
|
||||||
|
; CHECK-NEXT: loop.2: float = 0.0000000
|
||||||
|
loop.2:
|
||||||
|
%exit.2.cond = call i1 @foo()
|
||||||
|
br i1 %exit.2.cond, label %exit, label %loop.3, !prof !0
|
||||||
|
|
||||||
|
; CHECK-NEXT: loop.3: float = 0.0000000
|
||||||
|
loop.3:
|
||||||
|
%exit.3.cond = call i1 @foo()
|
||||||
|
br i1 %exit.3.cond, label %exit, label %loop.4, !prof !0
|
||||||
|
|
||||||
|
; CHECK-NEXT: loop.4: float = 0.0,
|
||||||
|
loop.4:
|
||||||
|
%exit.4.cond = call i1 @foo()
|
||||||
|
br i1 %exit.4.cond, label %exit, label %loop, !prof !0
|
||||||
|
|
||||||
|
; CHECK-NEXT: exit: float = 1.0, int = [[ENTRY]]
|
||||||
|
exit:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i1 @foo()
|
||||||
|
|
||||||
|
!0 = metadata !{metadata !"branch_weights", i32 4294967295, i32 1}
|
Loading…
Reference in New Issue
Block a user