diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp index 9c0216dba2a94..ac1e9fe1ca589 100644 --- a/llvm/lib/CodeGen/RegAllocGreedy.cpp +++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -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())); if (!CSRCost.getFrequency()) return; diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h index 0830191dde3f4..50d27641d6036 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h @@ -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; diff --git a/llvm/test/CodeGen/RISCV/csr-first-use-cost.ll b/llvm/test/CodeGen/RISCV/csr-first-use-cost.ll new file mode 100644 index 0000000000000..c6e5bae3c3c24 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/csr-first-use-cost.ll @@ -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 +}