[llvm] [RISCV] [MachineOutliner] Analyze all candidates (PR #127659)
Sudharsan Veeravalli via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 18 08:03:49 PST 2025
https://github.com/svs-quic updated https://github.com/llvm/llvm-project/pull/127659
>From 0e094e1e8e3c1c6b55ec27f5efd9d7e93e9e18c5 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Tue, 18 Feb 2025 20:57:48 +0530
Subject: [PATCH 1/2] Pre commit test
---
.../machine-outliner-call-x5-liveout.mir | 140 ++++++++++++++++++
1 file changed, 140 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir b/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
new file mode 100644
index 0000000000000..b2ca01faebce2
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
@@ -0,0 +1,140 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -mtriple=riscv32 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs < %s \
+# RUN: | FileCheck -check-prefixes=RV32I-MO %s
+# RUN: llc -mtriple=riscv64 -x mir -run-pass=machine-outliner -simplify-mir -verify-machineinstrs < %s \
+# RUN: | FileCheck -check-prefixes=RV64I-MO %s
+
+# MIR has been edited by hand to have x5 as live out in @dont_outline
+
+--- |
+ define i32 @outline_0(i32 %a, i32 %b) { ret i32 0 }
+
+ ; Can't outline if x5 is live out of the MBB
+ define i32 @dont_outline(i32 %a, i32 %b) { ret i32 0 }
+
+ define i32 @outline_1(i32 %a, i32 %b) { ret i32 0 }
+
+ define i32 @outline_2(i32 %a, i32 %b) { ret i32 0 }
+...
+---
+
+name: outline_0
+tracksRegLiveness: true
+isOutlined: false
+body: |
+ bb.0:
+ liveins: $x10, $x11
+
+ ; RV32I-MO-LABEL: name: outline_0
+ ; RV32I-MO: liveins: $x10, $x11
+ ; RV32I-MO-NEXT: {{ $}}
+ ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV32I-MO-NEXT: PseudoRET implicit $x11
+ ;
+ ; RV64I-MO-LABEL: name: outline_0
+ ; RV64I-MO: liveins: $x10, $x11
+ ; RV64I-MO-NEXT: {{ $}}
+ ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV64I-MO-NEXT: PseudoRET implicit $x11
+ $x11 = ORI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x10 = SUB $x10, $x11
+ PseudoRET implicit $x11
+
+...
+---
+
+name: dont_outline
+tracksRegLiveness: true
+isOutlined: false
+body: |
+ ; RV32I-MO-LABEL: name: dont_outline
+ ; RV32I-MO: bb.0:
+ ; RV32I-MO-NEXT: liveins: $x10, $x11
+ ; RV32I-MO-NEXT: {{ $}}
+ ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV32I-MO-NEXT: BEQ $x10, $x11, %bb.1
+ ; RV32I-MO-NEXT: {{ $}}
+ ; RV32I-MO-NEXT: bb.1:
+ ; RV32I-MO-NEXT: liveins: $x10, $x5
+ ; RV32I-MO-NEXT: {{ $}}
+ ; RV32I-MO-NEXT: PseudoRET implicit $x10, implicit $x5
+ ;
+ ; RV64I-MO-LABEL: name: dont_outline
+ ; RV64I-MO: bb.0:
+ ; RV64I-MO-NEXT: liveins: $x10, $x11
+ ; RV64I-MO-NEXT: {{ $}}
+ ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV64I-MO-NEXT: BEQ $x10, $x11, %bb.1
+ ; RV64I-MO-NEXT: {{ $}}
+ ; RV64I-MO-NEXT: bb.1:
+ ; RV64I-MO-NEXT: liveins: $x10, $x5
+ ; RV64I-MO-NEXT: {{ $}}
+ ; RV64I-MO-NEXT: PseudoRET implicit $x10, implicit $x5
+ bb.0:
+ liveins: $x10, $x11
+
+ $x11 = ORI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x10 = SUB $x10, $x11
+ BEQ $x10, $x11, %bb.1
+
+ bb.1:
+ liveins: $x10, $x5
+ PseudoRET implicit $x10, implicit $x5
+
+...
+---
+
+name: outline_1
+tracksRegLiveness: true
+isOutlined: false
+body: |
+ bb.0:
+ liveins: $x10, $x11
+
+ ; RV32I-MO-LABEL: name: outline_1
+ ; RV32I-MO: liveins: $x10, $x11
+ ; RV32I-MO-NEXT: {{ $}}
+ ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV32I-MO-NEXT: PseudoRET implicit $x10
+ ;
+ ; RV64I-MO-LABEL: name: outline_1
+ ; RV64I-MO: liveins: $x10, $x11
+ ; RV64I-MO-NEXT: {{ $}}
+ ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV64I-MO-NEXT: PseudoRET implicit $x10
+ $x11 = ORI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x10 = SUB $x10, $x11
+ PseudoRET implicit $x10
+
+...
+---
+name: outline_2
+tracksRegLiveness: true
+isOutlined: false
+body: |
+ bb.0:
+ liveins: $x10, $x11
+
+ ; RV32I-MO-LABEL: name: outline_2
+ ; RV32I-MO: liveins: $x10, $x11
+ ; RV32I-MO-NEXT: {{ $}}
+ ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV32I-MO-NEXT: PseudoRET implicit $x12
+ ;
+ ; RV64I-MO-LABEL: name: outline_2
+ ; RV64I-MO: liveins: $x10, $x11
+ ; RV64I-MO-NEXT: {{ $}}
+ ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV64I-MO-NEXT: PseudoRET implicit $x12
+ $x11 = ORI $x11, 1023
+ $x12 = ADDI $x10, 17
+ $x11 = AND $x12, $x11
+ $x10 = SUB $x10, $x11
+ PseudoRET implicit $x12
+...
>From 588fef888ade1f58665d8c705376fa189450138d Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Tue, 18 Feb 2025 21:33:06 +0530
Subject: [PATCH 2/2] Analyze all candidates
---
llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 52 ++++++++-----------
.../machine-outliner-call-x5-liveout.mir | 10 +++-
2 files changed, 30 insertions(+), 32 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 456fb66917216..bc859887c4aac 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -3015,30 +3015,25 @@ static bool cannotInsertTailCall(const MachineBasicBlock &MBB) {
return false;
}
-static std::optional<MachineOutlinerConstructionID>
-analyzeCandidate(outliner::Candidate &C) {
+static bool analyzeCandidate(outliner::Candidate &C) {
// If last instruction is return then we can rely on
// the verification already performed in the getOutliningTypeImpl.
if (C.back().isReturn()) {
assert(!cannotInsertTailCall(*C.getMBB()) &&
"The candidate who uses return instruction must be outlined "
"using tail call");
- return MachineOutlinerTailCall;
+ return false;
}
- auto CandidateUsesX5 = [](outliner::Candidate &C) {
- const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
- if (std::any_of(C.begin(), C.end(), [TRI](const MachineInstr &MI) {
- return isMIModifiesReg(MI, TRI, RISCV::X5);
- }))
- return true;
- return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
- };
-
- if (!CandidateUsesX5(C))
- return MachineOutlinerDefault;
+ // Filter out candidates where the X5 register (t0) can't be used to setup
+ // the function call.
+ const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
+ if (std::any_of(C.begin(), C.end(), [TRI](const MachineInstr &MI) {
+ return isMIModifiesReg(MI, TRI, RISCV::X5);
+ }))
+ return true;
- return std::nullopt;
+ return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
}
std::optional<std::unique_ptr<outliner::OutlinedFunction>>
@@ -3047,35 +3042,32 @@ RISCVInstrInfo::getOutliningCandidateInfo(
std::vector<outliner::Candidate> &RepeatedSequenceLocs,
unsigned MinRepeats) const {
- // Each RepeatedSequenceLoc is identical.
- outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
- auto CandidateInfo = analyzeCandidate(Candidate);
- if (!CandidateInfo)
- RepeatedSequenceLocs.clear();
+ // Analyze each candidate and erase the ones that are not viable.
+ llvm::erase_if(RepeatedSequenceLocs, analyzeCandidate);
// If the sequence doesn't have enough candidates left, then we're done.
if (RepeatedSequenceLocs.size() < MinRepeats)
return std::nullopt;
+ // Each RepeatedSequenceLoc is identical.
+ outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
unsigned InstrSizeCExt =
Candidate.getMF()->getSubtarget<RISCVSubtarget>().hasStdExtCOrZca() ? 2
: 4;
unsigned CallOverhead = 0, FrameOverhead = 0;
- MachineOutlinerConstructionID MOCI = CandidateInfo.value();
- switch (MOCI) {
- case MachineOutlinerDefault:
- // call t0, function = 8 bytes.
- CallOverhead = 8;
- // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
- FrameOverhead = InstrSizeCExt;
- break;
- case MachineOutlinerTailCall:
+ MachineOutlinerConstructionID MOCI = MachineOutlinerDefault;
+ if (Candidate.back().isReturn()) {
+ MOCI = MachineOutlinerTailCall;
// tail call = auipc + jalr in the worst case without linker relaxation.
CallOverhead = 4 + InstrSizeCExt;
// Using tail call we move ret instruction from caller to callee.
FrameOverhead = 0;
- break;
+ } else {
+ // call t0, function = 8 bytes.
+ CallOverhead = 8;
+ // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
+ FrameOverhead = InstrSizeCExt;
}
for (auto &C : RepeatedSequenceLocs)
diff --git a/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir b/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
index b2ca01faebce2..5da06850e5a67 100644
--- a/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
+++ b/llvm/test/CodeGen/RISCV/machine-outliner-call-x5-liveout.mir
@@ -53,7 +53,10 @@ body: |
; RV32I-MO: bb.0:
; RV32I-MO-NEXT: liveins: $x10, $x11
; RV32I-MO-NEXT: {{ $}}
- ; RV32I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV32I-MO-NEXT: $x11 = ORI $x11, 1023
+ ; RV32I-MO-NEXT: $x12 = ADDI $x10, 17
+ ; RV32I-MO-NEXT: $x11 = AND $x12, $x11
+ ; RV32I-MO-NEXT: $x10 = SUB $x10, $x11
; RV32I-MO-NEXT: BEQ $x10, $x11, %bb.1
; RV32I-MO-NEXT: {{ $}}
; RV32I-MO-NEXT: bb.1:
@@ -65,7 +68,10 @@ body: |
; RV64I-MO: bb.0:
; RV64I-MO-NEXT: liveins: $x10, $x11
; RV64I-MO-NEXT: {{ $}}
- ; RV64I-MO-NEXT: $x5 = PseudoCALLReg target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit-def $x5, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x10, implicit $x11
+ ; RV64I-MO-NEXT: $x11 = ORI $x11, 1023
+ ; RV64I-MO-NEXT: $x12 = ADDI $x10, 17
+ ; RV64I-MO-NEXT: $x11 = AND $x12, $x11
+ ; RV64I-MO-NEXT: $x10 = SUB $x10, $x11
; RV64I-MO-NEXT: BEQ $x10, $x11, %bb.1
; RV64I-MO-NEXT: {{ $}}
; RV64I-MO-NEXT: bb.1:
More information about the llvm-commits
mailing list