Skip to content

[RISCV][RegAlloc] Add getCSRFirstUseCost for RISC-V #131349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions llvm/lib/CodeGen/RegAllocGreedy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2375,10 +2375,12 @@ void RAGreedy::aboutToRemoveInterval(const LiveInterval &LI) {
}

void RAGreedy::initializeCSRCost() {
// We use the larger one out of the command-line option and the value report
// by TRI.
// We use the command-line option if it is explicitly set, otherwise use the
// larger one out of the command-line option and the value reported by TRI.
CSRCost = BlockFrequency(
std::max((unsigned)CSRFirstTimeCost, TRI->getCSRFirstUseCost()));
CSRFirstTimeCost.getNumOccurrences()
? CSRFirstTimeCost
: std::max((unsigned)CSRFirstTimeCost, TRI->getCSRFirstUseCost()));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the command line option isn't explicitly set, CSRFirstTimeCost will be the default value of 0 so this max will always return TRI->getCSRFirstUseCost()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone goes in and changes the default value, wouldn't we want the comparison to occur without having to change the code here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, but I'm not sure why the default of the CSRFirstTimeCost would be changed instead of the base class implementation of TargetRegisterInfo::getCSRFirstUseCost().

We can take the code how you have it.

if (!CSRCost.getFrequency())
return;

Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/RISCVRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ struct RISCVRegisterInfo : public RISCVGenRegisterInfo {
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID) const override;

unsigned getCSRFirstUseCost() const override {
// The cost will be compared against BlockFrequency where entry has the
// value of 1 << 14. A value of 5 will choose to spill or split cold
// path instead of using a callee-saved register.
return 5;
}

const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;

const MCPhysReg *getIPRACSRegs(const MachineFunction *MF) const override;
Expand Down
107 changes: 107 additions & 0 deletions llvm/test/CodeGen/RISCV/csr-first-use-cost.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=riscv64 -regalloc-csr-first-time-cost=0 < %s | FileCheck %s -check-prefix=ZERO-COST
; RUN: llc -mtriple=riscv64 < %s | FileCheck %s -check-prefix=DEFAULT-COST

define fastcc void @Perl_sv_setnv(i8 %c, ptr %.str.54.3682) nounwind {
; ZERO-COST-LABEL: Perl_sv_setnv:
; ZERO-COST: # %bb.0: # %entry
; ZERO-COST-NEXT: addi sp, sp, -32
; ZERO-COST-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; ZERO-COST-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; ZERO-COST-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
; ZERO-COST-NEXT: andi a0, a0, 255
; ZERO-COST-NEXT: li a2, 2
; ZERO-COST-NEXT: blt a2, a0, .LBB0_3
; ZERO-COST-NEXT: # %bb.1: # %entry
; ZERO-COST-NEXT: beqz a0, .LBB0_4
; ZERO-COST-NEXT: # %bb.2: # %entry
; ZERO-COST-NEXT: mv s0, a1
; ZERO-COST-NEXT: li a1, 1
; ZERO-COST-NEXT: beq a0, a1, .LBB0_6
; ZERO-COST-NEXT: j .LBB0_7
; ZERO-COST-NEXT: .LBB0_3: # %entry
; ZERO-COST-NEXT: li a2, 3
; ZERO-COST-NEXT: bne a0, a2, .LBB0_5
; ZERO-COST-NEXT: .LBB0_4: # %sw.bb3
; ZERO-COST-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; ZERO-COST-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; ZERO-COST-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
; ZERO-COST-NEXT: addi sp, sp, 32
; ZERO-COST-NEXT: ret
; ZERO-COST-NEXT: .LBB0_5: # %entry
; ZERO-COST-NEXT: mv s0, a1
; ZERO-COST-NEXT: li a1, 12
; ZERO-COST-NEXT: bne a0, a1, .LBB0_7
; ZERO-COST-NEXT: .LBB0_6: # %sw.bb34.i
; ZERO-COST-NEXT: li s0, 0
; ZERO-COST-NEXT: .LBB0_7: # %Perl_sv_reftype.exit
; ZERO-COST-NEXT: li s1, 0
; ZERO-COST-NEXT: li a0, 0
; ZERO-COST-NEXT: li a1, 0
; ZERO-COST-NEXT: jalr s1
; ZERO-COST-NEXT: li a0, 0
; ZERO-COST-NEXT: mv a1, s0
; ZERO-COST-NEXT: li a2, 0
; ZERO-COST-NEXT: jalr s1
;
; DEFAULT-COST-LABEL: Perl_sv_setnv:
; DEFAULT-COST: # %bb.0: # %entry
; DEFAULT-COST-NEXT: addi sp, sp, -32
; DEFAULT-COST-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
; DEFAULT-COST-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
; DEFAULT-COST-NEXT: andi a0, a0, 255
; DEFAULT-COST-NEXT: li a2, 2
; DEFAULT-COST-NEXT: blt a2, a0, .LBB0_3
; DEFAULT-COST-NEXT: # %bb.1: # %entry
; DEFAULT-COST-NEXT: beqz a0, .LBB0_4
; DEFAULT-COST-NEXT: # %bb.2: # %entry
; DEFAULT-COST-NEXT: sd a1, 8(sp) # 8-byte Folded Spill
; DEFAULT-COST-NEXT: li a1, 1
; DEFAULT-COST-NEXT: beq a0, a1, .LBB0_6
; DEFAULT-COST-NEXT: j .LBB0_7
; DEFAULT-COST-NEXT: .LBB0_3: # %entry
; DEFAULT-COST-NEXT: li a2, 3
; DEFAULT-COST-NEXT: bne a0, a2, .LBB0_5
; DEFAULT-COST-NEXT: .LBB0_4: # %sw.bb3
; DEFAULT-COST-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
; DEFAULT-COST-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
; DEFAULT-COST-NEXT: addi sp, sp, 32
; DEFAULT-COST-NEXT: ret
; DEFAULT-COST-NEXT: .LBB0_5: # %entry
; DEFAULT-COST-NEXT: sd a1, 8(sp) # 8-byte Folded Spill
; DEFAULT-COST-NEXT: li a1, 12
; DEFAULT-COST-NEXT: bne a0, a1, .LBB0_7
; DEFAULT-COST-NEXT: .LBB0_6: # %sw.bb34.i
; DEFAULT-COST-NEXT: sd zero, 8(sp) # 8-byte Folded Spill
; DEFAULT-COST-NEXT: .LBB0_7: # %Perl_sv_reftype.exit
; DEFAULT-COST-NEXT: li s0, 0
; DEFAULT-COST-NEXT: li a0, 0
; DEFAULT-COST-NEXT: li a1, 0
; DEFAULT-COST-NEXT: jalr s0
; DEFAULT-COST-NEXT: li a0, 0
; DEFAULT-COST-NEXT: ld a1, 8(sp) # 8-byte Folded Reload
; DEFAULT-COST-NEXT: li a2, 0
; DEFAULT-COST-NEXT: jalr s0
entry:
switch i8 %c, label %Perl_sv_reftype.exit [
i8 1, label %sw.bb4
i8 12, label %sw.bb34.i
i8 3, label %sw.bb3
i8 0, label %sw.bb3
]

sw.bb3: ; preds = %entry, %entry
ret void

sw.bb4: ; preds = %entry
br label %Perl_sv_reftype.exit

sw.bb34.i: ; preds = %entry
br label %Perl_sv_reftype.exit

Perl_sv_reftype.exit: ; preds = %sw.bb34.i, %sw.bb4, %entry
%retval.0.i = phi ptr [ null, %sw.bb34.i ], [ null, %sw.bb4 ], [ %.str.54.3682, %entry ]
%call17 = tail call fastcc i64 null(ptr null, i32 0)
tail call void (ptr, ...) null(ptr null, ptr %retval.0.i, ptr null)
unreachable
}