Skip to content

Commit 11e482c

Browse files
authored
RegAllocGreedy: Add dummy priority advisor for writing MIR tests (#121207)
I regularly struggle reproducing failures in greedy due to changes in priority when resuming the allocation from MIR vs. a complete compilation starting at IR. That is, the fix in e0919b1 did not really fix the problem of the instruction distance mattering. Add a way to bypass all of the priority heuristics for MIR tests, by prioritizing only by virtual register number. Could also give this a more specific name, like PrioritizeLowVirtRegNumber
1 parent 8ab88f1 commit 11e482c

File tree

4 files changed

+107
-2
lines changed

4 files changed

+107
-2
lines changed

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,12 @@ unsigned DefaultPriorityAdvisor::getPriority(const LiveInterval &LI) const {
376376
return Prio;
377377
}
378378

379+
unsigned DummyPriorityAdvisor::getPriority(const LiveInterval &LI) const {
380+
// Prioritize by virtual register number, lowest first.
381+
Register Reg = LI.reg();
382+
return ~Reg.virtRegIndex();
383+
}
384+
379385
const LiveInterval *RAGreedy::dequeue() { return dequeue(Queue); }
380386

381387
const LiveInterval *RAGreedy::dequeue(PQueue &CurQueue) {

llvm/lib/CodeGen/RegAllocPriorityAdvisor.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ static cl::opt<RegAllocPriorityAdvisorAnalysis::AdvisorMode> Mode(
3030
clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Release,
3131
"release", "precompiled"),
3232
clEnumValN(RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development,
33-
"development", "for training")));
33+
"development", "for training"),
34+
clEnumValN(
35+
RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy, "dummy",
36+
"prioritize low virtual register numbers for test and debug")));
3437

3538
char RegAllocPriorityAdvisorAnalysis::ID = 0;
3639
INITIALIZE_PASS(RegAllocPriorityAdvisorAnalysis, "regalloc-priority",
@@ -67,6 +70,31 @@ class DefaultPriorityAdvisorAnalysis final
6770
}
6871
const bool NotAsRequested;
6972
};
73+
74+
class DummyPriorityAdvisorAnalysis final
75+
: public RegAllocPriorityAdvisorAnalysis {
76+
public:
77+
DummyPriorityAdvisorAnalysis()
78+
: RegAllocPriorityAdvisorAnalysis(AdvisorMode::Dummy) {}
79+
80+
// support for isa<> and dyn_cast.
81+
static bool classof(const RegAllocPriorityAdvisorAnalysis *R) {
82+
return R->getAdvisorMode() == AdvisorMode::Dummy;
83+
}
84+
85+
private:
86+
void getAnalysisUsage(AnalysisUsage &AU) const override {
87+
AU.addRequired<SlotIndexesWrapperPass>();
88+
RegAllocPriorityAdvisorAnalysis::getAnalysisUsage(AU);
89+
}
90+
91+
std::unique_ptr<RegAllocPriorityAdvisor>
92+
getAdvisor(const MachineFunction &MF, const RAGreedy &RA) override {
93+
return std::make_unique<DummyPriorityAdvisor>(
94+
MF, RA, &getAnalysis<SlotIndexesWrapperPass>().getSI());
95+
}
96+
};
97+
7098
} // namespace
7199

72100
template <> Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysis>() {
@@ -75,6 +103,9 @@ template <> Pass *llvm::callDefaultCtor<RegAllocPriorityAdvisorAnalysis>() {
75103
case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Default:
76104
Ret = new DefaultPriorityAdvisorAnalysis(/*NotAsRequested*/ false);
77105
break;
106+
case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Dummy:
107+
Ret = new DummyPriorityAdvisorAnalysis();
108+
break;
78109
case RegAllocPriorityAdvisorAnalysis::AdvisorMode::Development:
79110
#if defined(LLVM_HAVE_TFLITE)
80111
Ret = createDevelopmentModePriorityAdvisor();
@@ -97,6 +128,8 @@ StringRef RegAllocPriorityAdvisorAnalysis::getPassName() const {
97128
return "Release mode Regalloc Priority Advisor";
98129
case AdvisorMode::Development:
99130
return "Development mode Regalloc Priority Advisor";
131+
case AdvisorMode::Dummy:
132+
return "Dummy Regalloc Priority Advisor";
100133
}
101134
llvm_unreachable("Unknown advisor kind");
102135
}

llvm/lib/CodeGen/RegAllocPriorityAdvisor.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,21 @@ class DefaultPriorityAdvisor : public RegAllocPriorityAdvisor {
5656
unsigned getPriority(const LiveInterval &LI) const override;
5757
};
5858

59+
/// Stupid priority advisor which just enqueues in virtual register number
60+
/// order, for debug purposes only.
61+
class DummyPriorityAdvisor : public RegAllocPriorityAdvisor {
62+
public:
63+
DummyPriorityAdvisor(const MachineFunction &MF, const RAGreedy &RA,
64+
SlotIndexes *const Indexes)
65+
: RegAllocPriorityAdvisor(MF, RA, Indexes) {}
66+
67+
private:
68+
unsigned getPriority(const LiveInterval &LI) const override;
69+
};
70+
5971
class RegAllocPriorityAdvisorAnalysis : public ImmutablePass {
6072
public:
61-
enum class AdvisorMode : int { Default, Release, Development };
73+
enum class AdvisorMode : int { Default, Release, Development, Dummy };
6274

6375
RegAllocPriorityAdvisorAnalysis(AdvisorMode Mode)
6476
: ImmutablePass(ID), Mode(Mode){};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -start-before=greedy,2 -stress-regalloc=4 -stop-after=virtregrewriter,2 -regalloc-enable-priority-advisor=default -o - %s | FileCheck -check-prefixes=CHECK,DEFAULT %s
3+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -start-before=greedy,2 -stress-regalloc=4 -stop-after=virtregrewriter,2 -regalloc-enable-priority-advisor=dummy -o - %s | FileCheck -check-prefixes=CHECK,DUMMY %s
4+
5+
# Check that the regalloc-enable-priority-advisor=dummy option works
6+
# and the result is different from the default. Ordinarily %1 would be
7+
# prioritized higher than %0 due to the register class priority
8+
9+
---
10+
name: foo
11+
tracksRegLiveness: true
12+
machineFunctionInfo:
13+
scratchRSrcReg: '$sgpr0_sgpr1_sgpr2_sgpr3'
14+
frameOffsetReg: '$sgpr33'
15+
stackPtrOffsetReg: '$sgpr32'
16+
registers:
17+
- { id: 0, class: vgpr_32 }
18+
- { id: 1, class: vreg_128 }
19+
- { id: 2, class: vgpr_32 }
20+
body: |
21+
bb.0:
22+
liveins: $vgpr0, $vgpr1
23+
24+
; DEFAULT-LABEL: name: foo
25+
; DEFAULT: liveins: $vgpr0, $vgpr1
26+
; DEFAULT-NEXT: {{ $}}
27+
; DEFAULT-NEXT: SI_SPILL_V128_SAVE $vgpr1_vgpr2_vgpr3_vgpr4, %stack.0, $sgpr32, 0, implicit $exec :: (store (s128) into %stack.0, align 4, addrspace 5)
28+
; DEFAULT-NEXT: SI_SPILL_V32_SAVE $vgpr0, %stack.1, $sgpr32, 0, implicit $exec :: (store (s32) into %stack.1, addrspace 5)
29+
; DEFAULT-NEXT: S_NOP 0, implicit-def $vgpr0_vgpr1_vgpr2_vgpr3
30+
; DEFAULT-NEXT: renamable $vgpr2_vgpr3_vgpr4_vgpr5 = SI_SPILL_V128_RESTORE %stack.0, $sgpr32, 0, implicit $exec :: (load (s128) from %stack.0, align 4, addrspace 5)
31+
; DEFAULT-NEXT: renamable $vgpr3 = SI_SPILL_V32_RESTORE %stack.1, $sgpr32, 0, implicit $exec :: (load (s32) from %stack.1, addrspace 5)
32+
; DEFAULT-NEXT: renamable $vgpr3 = V_ADD_U32_e32 killed $vgpr2, killed $vgpr3, implicit $exec
33+
; DEFAULT-NEXT: SI_RETURN implicit $vgpr3, implicit $vgpr0, implicit $vgpr1
34+
;
35+
; DUMMY-LABEL: name: foo
36+
; DUMMY: liveins: $vgpr0, $vgpr1
37+
; DUMMY-NEXT: {{ $}}
38+
; DUMMY-NEXT: SI_SPILL_V128_SAVE $vgpr1_vgpr2_vgpr3_vgpr4, %stack.1, $sgpr32, 0, implicit $exec :: (store (s128) into %stack.1, align 4, addrspace 5)
39+
; DUMMY-NEXT: SI_SPILL_V32_SAVE $vgpr0, %stack.0, $sgpr32, 0, implicit $exec :: (store (s32) into %stack.0, addrspace 5)
40+
; DUMMY-NEXT: S_NOP 0, implicit-def $vgpr0_vgpr1_vgpr2_vgpr3
41+
; DUMMY-NEXT: renamable $vgpr2 = SI_SPILL_V32_RESTORE %stack.0, $sgpr32, 0, implicit $exec :: (load (s32) from %stack.0, addrspace 5)
42+
; DUMMY-NEXT: renamable $vgpr3_vgpr4_vgpr5_vgpr6 = SI_SPILL_V128_RESTORE %stack.1, $sgpr32, 0, implicit $exec :: (load (s128) from %stack.1, align 4, addrspace 5)
43+
; DUMMY-NEXT: renamable $vgpr3 = V_ADD_U32_e32 killed $vgpr3, killed $vgpr2, implicit $exec
44+
; DUMMY-NEXT: SI_RETURN implicit $vgpr3, implicit $vgpr0, implicit $vgpr1
45+
undef %1.sub0:vreg_128 = COPY $vgpr1
46+
%0:vgpr_32 = COPY $vgpr0
47+
S_NOP 0, implicit-def $vgpr0_vgpr1_vgpr2_vgpr3
48+
%2:vgpr_32 = V_ADD_U32_e32 %1.sub0, %0, implicit $exec
49+
$vgpr3 = COPY %2
50+
SI_RETURN implicit $vgpr3, implicit $vgpr0, implicit $vgpr1
51+
52+
...
53+
54+
# CHECK: {{.*}}

0 commit comments

Comments
 (0)