Skip to content

Commit f94bd3c

Browse files
authored
Revert "[RISCV] Implement tail call optimization in machine outliner" (llvm#117710)
Reverts llvm#115297 Bots are broken
1 parent 827ebf8 commit f94bd3c

10 files changed

+79
-298
lines changed

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,6 @@ static inline unsigned getVLOpNum(const MCInstrDesc &Desc) {
208208
return Desc.getNumOperands() - Offset;
209209
}
210210

211-
static inline unsigned getTailExpandUseRegNo(const FeatureBitset &FeatureBits) {
212-
// For Zicfilp, PseudoTAIL should be expanded to a software guarded branch.
213-
// It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL.
214-
return FeatureBits[RISCV::FeatureStdExtZicfilp] ? RISCV::X7 : RISCV::X6;
215-
}
216-
217211
static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) {
218212
const uint64_t TSFlags = Desc.TSFlags;
219213
assert(hasSEWOp(TSFlags));

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI,
124124
MCRegister Ra;
125125
if (MI.getOpcode() == RISCV::PseudoTAIL) {
126126
Func = MI.getOperand(0);
127-
Ra = RISCVII::getTailExpandUseRegNo(STI.getFeatureBits());
127+
Ra = RISCV::X6;
128+
// For Zicfilp, PseudoTAIL should be expanded to a software guarded branch.
129+
// It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL.
130+
if (STI.hasFeature(RISCV::FeatureStdExtZicfilp))
131+
Ra = RISCV::X7;
128132
} else if (MI.getOpcode() == RISCV::PseudoCALLReg) {
129133
Func = MI.getOperand(1);
130134
Ra = MI.getOperand(0).getReg();

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 33 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "RISCVInstrInfo.h"
14-
#include "MCTargetDesc/RISCVBaseInfo.h"
1514
#include "MCTargetDesc/RISCVMatInt.h"
1615
#include "RISCV.h"
1716
#include "RISCVMachineFunctionInfo.h"
@@ -2928,7 +2927,6 @@ bool RISCVInstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
29282927

29292928
// Enum values indicating how an outlined call should be constructed.
29302929
enum MachineOutlinerConstructionID {
2931-
MachineOutlinerTailCall,
29322930
MachineOutlinerDefault
29332931
};
29342932

@@ -2937,118 +2935,46 @@ bool RISCVInstrInfo::shouldOutlineFromFunctionByDefault(
29372935
return MF.getFunction().hasMinSize();
29382936
}
29392937

2940-
static bool isCandidatePatchable(const MachineBasicBlock &MBB) {
2941-
const MachineFunction *MF = MBB.getParent();
2942-
const Function &F = MF->getFunction();
2943-
return F.getFnAttribute("fentry-call").getValueAsBool() ||
2944-
F.hasFnAttribute("patchable-function-entry");
2945-
}
2946-
2947-
static bool isMIReadsReg(const MachineInstr &MI, const TargetRegisterInfo *TRI,
2948-
unsigned RegNo) {
2949-
return MI.readsRegister(RegNo, TRI) ||
2950-
MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
2951-
}
2952-
2953-
static bool isMIModifiesReg(const MachineInstr &MI,
2954-
const TargetRegisterInfo *TRI, unsigned RegNo) {
2955-
return MI.modifiesRegister(RegNo, TRI) ||
2956-
MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
2957-
}
2958-
2959-
static bool cannotInsertTailCall(const MachineBasicBlock &MBB) {
2960-
if (!MBB.back().isReturn())
2961-
return true;
2962-
if (isCandidatePatchable(MBB))
2963-
return true;
2964-
2965-
// If the candidate reads the pre-set register
2966-
// that can be used for expanding PseudoTAIL instruction,
2967-
// then we cannot insert tail call.
2968-
const TargetSubtargetInfo &STI = MBB.getParent()->getSubtarget();
2969-
unsigned TailExpandUseRegNo =
2970-
RISCVII::getTailExpandUseRegNo(STI.getFeatureBits());
2971-
for (const MachineInstr &MI : MBB) {
2972-
if (isMIReadsReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
2973-
return true;
2974-
if (isMIModifiesReg(MI, STI.getRegisterInfo(), TailExpandUseRegNo))
2975-
break;
2976-
}
2977-
return false;
2978-
}
2979-
2980-
static std::optional<MachineOutlinerConstructionID>
2981-
analyzeCandidate(outliner::Candidate &C) {
2982-
// If last instruction is return then we can rely on
2983-
// the verification already performed in the getOutliningTypeImpl.
2984-
if (C.back().isReturn()) {
2985-
assert(!cannotInsertTailCall(*C.getMBB()) &&
2986-
"The candidate who uses return instruction must be outlined "
2987-
"using tail call");
2988-
return MachineOutlinerTailCall;
2989-
}
2990-
2991-
auto CandidateUsesX5 = [](outliner::Candidate &C) {
2992-
const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
2993-
if (std::any_of(C.begin(), C.end(), [TRI](const MachineInstr &MI) {
2994-
return isMIModifiesReg(MI, TRI, RISCV::X5);
2995-
}))
2996-
return true;
2997-
return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
2998-
};
2999-
3000-
if (!CandidateUsesX5(C))
3001-
return MachineOutlinerDefault;
3002-
3003-
return std::nullopt;
3004-
}
3005-
30062938
std::optional<std::unique_ptr<outliner::OutlinedFunction>>
30072939
RISCVInstrInfo::getOutliningCandidateInfo(
30082940
const MachineModuleInfo &MMI,
30092941
std::vector<outliner::Candidate> &RepeatedSequenceLocs,
30102942
unsigned MinRepeats) const {
30112943

3012-
// Each RepeatedSequenceLoc is identical.
3013-
outliner::Candidate &Candidate = RepeatedSequenceLocs[0];
3014-
auto CandidateInfo = analyzeCandidate(Candidate);
3015-
if (!CandidateInfo)
3016-
RepeatedSequenceLocs.clear();
2944+
// First we need to filter out candidates where the X5 register (IE t0) can't
2945+
// be used to setup the function call.
2946+
auto CannotInsertCall = [](outliner::Candidate &C) {
2947+
const TargetRegisterInfo *TRI = C.getMF()->getSubtarget().getRegisterInfo();
2948+
return !C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *TRI);
2949+
};
2950+
2951+
llvm::erase_if(RepeatedSequenceLocs, CannotInsertCall);
30172952

30182953
// If the sequence doesn't have enough candidates left, then we're done.
30192954
if (RepeatedSequenceLocs.size() < MinRepeats)
30202955
return std::nullopt;
30212956

3022-
unsigned InstrSizeCExt =
3023-
Candidate.getMF()->getSubtarget<RISCVSubtarget>().hasStdExtCOrZca() ? 2
3024-
: 4;
3025-
unsigned CallOverhead = 0, FrameOverhead = 0;
3026-
3027-
MachineOutlinerConstructionID MOCI = CandidateInfo.value();
3028-
switch (MOCI) {
3029-
case MachineOutlinerDefault:
3030-
// call t0, function = 8 bytes.
3031-
CallOverhead = 8;
3032-
// jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3033-
FrameOverhead = InstrSizeCExt;
3034-
break;
3035-
case MachineOutlinerTailCall:
3036-
// tail call = auipc + jalr in the worst case without linker relaxation.
3037-
CallOverhead = 4 + InstrSizeCExt;
3038-
// Using tail call we move ret instruction from caller to callee.
3039-
FrameOverhead = 0;
3040-
break;
3041-
}
2957+
unsigned SequenceSize = 0;
2958+
2959+
for (auto &MI : RepeatedSequenceLocs[0])
2960+
SequenceSize += getInstSizeInBytes(MI);
30422961

2962+
// call t0, function = 8 bytes.
2963+
unsigned CallOverhead = 8;
30432964
for (auto &C : RepeatedSequenceLocs)
3044-
C.setCallInfo(MOCI, CallOverhead);
2965+
C.setCallInfo(MachineOutlinerDefault, CallOverhead);
30452966

3046-
unsigned SequenceSize = 0;
3047-
for (auto &MI : Candidate)
3048-
SequenceSize += getInstSizeInBytes(MI);
2967+
// jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
2968+
unsigned FrameOverhead = 4;
2969+
if (RepeatedSequenceLocs[0]
2970+
.getMF()
2971+
->getSubtarget<RISCVSubtarget>()
2972+
.hasStdExtCOrZca())
2973+
FrameOverhead = 2;
30492974

30502975
return std::make_unique<outliner::OutlinedFunction>(
3051-
RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
2976+
RepeatedSequenceLocs, SequenceSize, FrameOverhead,
2977+
MachineOutlinerDefault);
30522978
}
30532979

30542980
outliner::InstrType
@@ -3069,8 +2995,15 @@ RISCVInstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
30692995
return F.needsUnwindTableEntry() ? outliner::InstrType::Illegal
30702996
: outliner::InstrType::Invisible;
30712997

3072-
if (cannotInsertTailCall(*MBB) &&
3073-
(MI.isReturn() || isMIModifiesReg(MI, TRI, RISCV::X5)))
2998+
// We need support for tail calls to outlined functions before return
2999+
// statements can be allowed.
3000+
if (MI.isReturn())
3001+
return outliner::InstrType::Illegal;
3002+
3003+
// Don't allow modifying the X5 register which we use for return addresses for
3004+
// these outlined functions.
3005+
if (MI.modifiesRegister(RISCV::X5, TRI) ||
3006+
MI.getDesc().hasImplicitDefOfPhysReg(RISCV::X5))
30743007
return outliner::InstrType::Illegal;
30753008

30763009
// Make sure the operands don't reference something unsafe.
@@ -3106,9 +3039,6 @@ void RISCVInstrInfo::buildOutlinedFrame(
31063039
}
31073040
}
31083041

3109-
if (OF.FrameConstructionID == MachineOutlinerTailCall)
3110-
return;
3111-
31123042
MBB.addLiveIn(RISCV::X5);
31133043

31143044
// Add in a return instruction to the end of the outlined frame.
@@ -3122,13 +3052,6 @@ MachineBasicBlock::iterator RISCVInstrInfo::insertOutlinedCall(
31223052
Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It,
31233053
MachineFunction &MF, outliner::Candidate &C) const {
31243054

3125-
if (C.CallConstructionID == MachineOutlinerTailCall) {
3126-
It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(RISCV::PseudoTAIL))
3127-
.addGlobalAddress(M.getNamedValue(MF.getName()),
3128-
/*Offset=*/0, RISCVII::MO_CALL));
3129-
return It;
3130-
}
3131-
31323055
// Add in a call instruction to the outlined function at the given location.
31333056
It = MBB.insert(It,
31343057
BuildMI(MF, DebugLoc(), get(RISCV::PseudoCALLReg), RISCV::X5)

llvm/test/CodeGen/RISCV/machine-outliner-call.ll

Lines changed: 0 additions & 70 deletions
This file was deleted.

llvm/test/CodeGen/RISCV/machine-outliner-cfi.mir

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ body: |
2222
; RV32I-MO-LABEL: name: func1
2323
; RV32I-MO: liveins: $x10, $x11
2424
; RV32I-MO-NEXT: {{ $}}
25-
; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
25+
; 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
26+
; RV32I-MO-NEXT: PseudoRET
2627
; RV64I-MO-LABEL: name: func1
2728
; RV64I-MO: liveins: $x10, $x11
2829
; RV64I-MO-NEXT: {{ $}}
29-
; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
30+
; 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
31+
; RV64I-MO-NEXT: PseudoRET
3032
$x10 = ORI $x10, 1023
3133
CFI_INSTRUCTION offset $x1, 0
3234
$x11 = ORI $x11, 1023
@@ -47,11 +49,13 @@ body: |
4749
; RV32I-MO-LABEL: name: func2
4850
; RV32I-MO: liveins: $x10, $x11
4951
; RV32I-MO-NEXT: {{ $}}
50-
; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
52+
; 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
53+
; RV32I-MO-NEXT: PseudoRET
5154
; RV64I-MO-LABEL: name: func2
5255
; RV64I-MO: liveins: $x10, $x11
5356
; RV64I-MO-NEXT: {{ $}}
54-
; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
57+
; 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
58+
; RV64I-MO-NEXT: PseudoRET
5559
$x10 = ORI $x10, 1023
5660
CFI_INSTRUCTION offset $x1, 0
5761
$x11 = ORI $x11, 1023
@@ -72,11 +76,13 @@ body: |
7276
; RV32I-MO-LABEL: name: func3
7377
; RV32I-MO: liveins: $x10, $x11
7478
; RV32I-MO-NEXT: {{ $}}
75-
; RV32I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
79+
; 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
80+
; RV32I-MO-NEXT: PseudoRET
7681
; RV64I-MO-LABEL: name: func3
7782
; RV64I-MO: liveins: $x10, $x11
7883
; RV64I-MO-NEXT: {{ $}}
79-
; RV64I-MO-NEXT: PseudoTAIL target-flags(riscv-call) @OUTLINED_FUNCTION_0, implicit $x2, implicit-def $x10, implicit-def $x11, implicit-def $x12, implicit $x2, implicit $x10, implicit $x11
84+
; 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
85+
; RV64I-MO-NEXT: PseudoRET
8086
$x10 = ORI $x10, 1023
8187
CFI_INSTRUCTION offset $x1, -12
8288
$x11 = ORI $x11, 1023
@@ -90,11 +96,11 @@ body: |
9096
9197
9298
# OUTLINED-LABEL: name: OUTLINED_FUNCTION_0
93-
# OUTLINED: liveins: $x11, $x10
99+
# OUTLINED: liveins: $x11, $x10, $x5
94100
# OUTLINED-NEXT: {{ $}}
95101
# OUTLINED-NEXT: $x10 = ORI $x10, 1023
96102
# OUTLINED-NEXT: $x11 = ORI $x11, 1023
97103
# OUTLINED-NEXT: $x12 = ADDI $x10, 17
98104
# OUTLINED-NEXT: $x11 = AND $x12, $x11
99105
# OUTLINED-NEXT: $x10 = SUB $x10, $x11
100-
# OUTLINED-NEXT: PseudoRET
106+
# OUTLINED-NEXT: $x0 = JALR $x5, 0

llvm/test/CodeGen/RISCV/machine-outliner-leaf-descendants.ll

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,25 @@ define i32 @_Z2f6v() minsize {
9494
; CHECK-BASELINE-NEXT: li a3, 0x4
9595
; CHECK-BASELINE-NEXT: li a4, 0x5
9696
; CHECK-BASELINE-NEXT: li a5, 0x6
97-
; CHECK-BASELINE-NEXT: auipc t1, 0x0
98-
; CHECK-BASELINE-NEXT: jr t1
97+
; CHECK-BASELINE-NEXT: jr t0
9998

10099
; CHECK-BASELINE: <OUTLINED_FUNCTION_1>:
101100
; CHECK-BASELINE-NEXT: li a0, 0x1
102101
; CHECK-BASELINE-NEXT: li a1, 0x2
103102
; CHECK-BASELINE-NEXT: li a2, 0x3
104103
; CHECK-BASELINE-NEXT: li a3, 0x4
105104
; CHECK-BASELINE-NEXT: li a4, 0x5
106-
; CHECK-BASELINE-NEXT: li a5, 0x8
107-
; CHECK-BASELINE-NEXT: auipc t1, 0x0
108-
; CHECK-BASELINE-NEXT: jr t1
105+
; CHECK-BASELINE-NEXT: li a5, 0x7
106+
; CHECK-BASELINE-NEXT: jr t0
109107

110108
; CHECK-BASELINE: <OUTLINED_FUNCTION_2>:
111109
; CHECK-BASELINE-NEXT: li a0, 0x1
112110
; CHECK-BASELINE-NEXT: li a1, 0x2
113111
; CHECK-BASELINE-NEXT: li a2, 0x3
114112
; CHECK-BASELINE-NEXT: li a3, 0x4
115113
; CHECK-BASELINE-NEXT: li a4, 0x5
116-
; CHECK-BASELINE-NEXT: li a5, 0x7
117-
; CHECK-BASELINE-NEXT: auipc t1, 0x0
118-
; CHECK-BASELINE-NEXT: jr t1
114+
; CHECK-BASELINE-NEXT: li a5, 0x8
115+
; CHECK-BASELINE-NEXT: jr t0
119116

120117
; CHECK-LEAF-DESCENDANTS: <OUTLINED_FUNCTION_0>:
121118
; CHECK-LEAF-DESCENDANTS-NEXT: li a0, 0x1

0 commit comments

Comments
 (0)