Skip to content

Commit cd0cf21

Browse files
committed
[RegAllocEvictAdvisor][NFC] Add minimum weight ratio heuristic.
Do not evict a live range if eviction will break existing hint without satisfying a new one and the ratio of weights is not big enough. The heuristic is disabled by default.
1 parent befd44b commit cd0cf21

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

llvm/lib/CodeGen/RegAllocEvictionAdvisor.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ static cl::opt<bool> EnableLocalReassignment(
4444
"may be compile time intensive"),
4545
cl::init(false));
4646

47+
static cl::opt<float> MinWeightRatioNeededToEvictHint(
48+
"min-weight-ratio-needed-to-evict-hint", cl::Hidden,
49+
cl::desc("The minimum ratio of weights needed in order for the live range "
50+
"with bigger weight to evict the other live range which"
51+
"satisfies a hint"),
52+
cl::init(1.0));
53+
4754
namespace llvm {
4855
cl::opt<unsigned> EvictInterferenceCutoff(
4956
"regalloc-eviction-max-interference-cutoff", cl::Hidden,
@@ -156,8 +163,15 @@ bool DefaultEvictionAdvisor::shouldEvict(const LiveInterval &A, bool IsHint,
156163
if (CanSplit && IsHint && !BreaksHint)
157164
return true;
158165

159-
if (A.weight() > B.weight()) {
160-
LLVM_DEBUG(dbgs() << "should evict: " << B << " w= " << B.weight() << '\n');
166+
float AWeight = A.weight();
167+
float BWeight = B.weight();
168+
if (AWeight > BWeight) {
169+
float WeightRatio = BWeight == 0.0 ? std::numeric_limits<float>::infinity()
170+
: AWeight / BWeight;
171+
if (CanSplit && !IsHint && BreaksHint &&
172+
(WeightRatio < MinWeightRatioNeededToEvictHint))
173+
return false;
174+
LLVM_DEBUG(dbgs() << "should evict: " << B << " w= " << BWeight << '\n');
161175
return true;
162176
}
163177
return false;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc %s -mtriple=riscv64 -run-pass=greedy,virtregrewriter \
3+
# RUN: -min-weight-ratio-needed-to-evict-hint=7.5 -o - | FileCheck %s
4+
5+
# Due to the minimum weight heuristic (see the explanation of `MinWeightRatioNeededToEvictHint`) we are able to get rid of ALL the copies in the code below. When heuristic is disabled (-min-weight-ratio-needed-to-evict-hint=1.0) we end up with 3 copies.
6+
7+
--- |
8+
source_filename = "test.c"
9+
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
10+
target triple = "riscv64"
11+
12+
define dso_local i64 @caller(i64 %x) {
13+
entry:
14+
%add_ = add i64 %x, 1
15+
call void @foo()
16+
ret i64 %add_
17+
}
18+
19+
declare void @foo()
20+
21+
...
22+
---
23+
name: caller
24+
alignment: 2
25+
tracksRegLiveness: true
26+
body: |
27+
bb.0.entry:
28+
liveins: $x10, $x1, $x8, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
29+
30+
; CHECK-LABEL: name: caller
31+
; CHECK: liveins: $x1, $x8, $x9, $x10, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
32+
; CHECK-NEXT: {{ $}}
33+
; CHECK-NEXT: SD $x1, %stack.0, 0 :: (store (s64) into %stack.0)
34+
; CHECK-NEXT: renamable $x10 = ADDI killed renamable $x10, 1
35+
; CHECK-NEXT: SD killed renamable $x10, %stack.1, 0 :: (store (s64) into %stack.1)
36+
; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $x2, implicit $x2
37+
; CHECK-NEXT: PseudoCALL target-flags(riscv-call) @foo, csr_ilp32d_lp64d, implicit-def dead $x1, implicit-def $x2
38+
; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
39+
; CHECK-NEXT: $x10 = LD %stack.1, 0 :: (load (s64) from %stack.1)
40+
; CHECK-NEXT: $x1 = LD %stack.0, 0 :: (load (s64) from %stack.0)
41+
; CHECK-NEXT: PseudoRET implicit $x10, implicit $x1, implicit $x8, implicit $x9, implicit $x18, implicit $x19, implicit $x20, implicit $x21, implicit $x22, implicit $x23, implicit $x24, implicit $x25, implicit $x26, implicit $x27
42+
%14:gpr = COPY $x27
43+
%13:gpr = COPY $x26
44+
%12:gpr = COPY $x25
45+
%11:gpr = COPY $x24
46+
%10:gpr = COPY $x23
47+
%9:gpr = COPY $x22
48+
%8:gpr = COPY $x21
49+
%7:gpr = COPY $x20
50+
%6:gpr = COPY $x19
51+
%5:gpr = COPY $x18
52+
%4:gprc_and_sr07 = COPY $x9
53+
%3:gprc_and_sr07 = COPY $x8
54+
%2:gpr = COPY $x1
55+
%0:gpr = COPY $x10
56+
%1:gpr = ADDI %0, 1
57+
ADJCALLSTACKDOWN 0, 0, implicit-def dead $x2, implicit $x2
58+
PseudoCALL target-flags(riscv-call) @foo, csr_ilp32d_lp64d, implicit-def dead $x1, implicit-def $x2
59+
ADJCALLSTACKUP 0, 0, implicit-def dead $x2, implicit $x2
60+
$x10 = COPY %1
61+
$x1 = COPY %2
62+
$x8 = COPY %3
63+
$x9 = COPY %4
64+
$x18 = COPY %5
65+
$x19 = COPY %6
66+
$x20 = COPY %7
67+
$x21 = COPY %8
68+
$x22 = COPY %9
69+
$x23 = COPY %10
70+
$x24 = COPY %11
71+
$x25 = COPY %12
72+
$x26 = COPY %13
73+
$x27 = COPY %14
74+
PseudoRET implicit $x10, implicit $x1, implicit $x8, implicit $x9, implicit $x18, implicit $x19, implicit $x20, implicit $x21, implicit $x22, implicit $x23, implicit $x24, implicit $x25, implicit $x26, implicit $x27
75+
76+
...

0 commit comments

Comments
 (0)