@@ -3015,30 +3015,25 @@ static bool cannotInsertTailCall(const MachineBasicBlock &MBB) {
30153015 return false ;
30163016}
30173017
3018- static std::optional<MachineOutlinerConstructionID>
3019- analyzeCandidate (outliner::Candidate &C) {
3018+ static bool analyzeCandidate (outliner::Candidate &C) {
30203019 // If last instruction is return then we can rely on
30213020 // the verification already performed in the getOutliningTypeImpl.
30223021 if (C.back ().isReturn ()) {
30233022 assert (!cannotInsertTailCall (*C.getMBB ()) &&
30243023 " The candidate who uses return instruction must be outlined "
30253024 " using tail call" );
3026- return MachineOutlinerTailCall ;
3025+ return false ;
30273026 }
30283027
3029- auto CandidateUsesX5 = [](outliner::Candidate &C) {
3030- const TargetRegisterInfo *TRI = C.getMF ()->getSubtarget ().getRegisterInfo ();
3031- if (std::any_of (C.begin (), C.end (), [TRI](const MachineInstr &MI) {
3032- return isMIModifiesReg (MI, TRI, RISCV::X5);
3033- }))
3034- return true ;
3035- return !C.isAvailableAcrossAndOutOfSeq (RISCV::X5, *TRI);
3036- };
3037-
3038- if (!CandidateUsesX5 (C))
3039- return MachineOutlinerDefault;
3028+ // Filter out candidates where the X5 register (t0) can't be used to setup
3029+ // the function call.
3030+ const TargetRegisterInfo *TRI = C.getMF ()->getSubtarget ().getRegisterInfo ();
3031+ if (std::any_of (C.begin (), C.end (), [TRI](const MachineInstr &MI) {
3032+ return isMIModifiesReg (MI, TRI, RISCV::X5);
3033+ }))
3034+ return true ;
30403035
3041- return std:: nullopt ;
3036+ return !C. isAvailableAcrossAndOutOfSeq (RISCV::X5, *TRI) ;
30423037}
30433038
30443039std::optional<std::unique_ptr<outliner::OutlinedFunction>>
@@ -3047,35 +3042,32 @@ RISCVInstrInfo::getOutliningCandidateInfo(
30473042 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
30483043 unsigned MinRepeats) const {
30493044
3050- // Each RepeatedSequenceLoc is identical.
3051- outliner::Candidate &Candidate = RepeatedSequenceLocs[0 ];
3052- auto CandidateInfo = analyzeCandidate (Candidate);
3053- if (!CandidateInfo)
3054- RepeatedSequenceLocs.clear ();
3045+ // Analyze each candidate and erase the ones that are not viable.
3046+ llvm::erase_if (RepeatedSequenceLocs, analyzeCandidate);
30553047
30563048 // If the sequence doesn't have enough candidates left, then we're done.
30573049 if (RepeatedSequenceLocs.size () < MinRepeats)
30583050 return std::nullopt ;
30593051
3052+ // Each RepeatedSequenceLoc is identical.
3053+ outliner::Candidate &Candidate = RepeatedSequenceLocs[0 ];
30603054 unsigned InstrSizeCExt =
30613055 Candidate.getMF ()->getSubtarget <RISCVSubtarget>().hasStdExtCOrZca () ? 2
30623056 : 4 ;
30633057 unsigned CallOverhead = 0 , FrameOverhead = 0 ;
30643058
3065- MachineOutlinerConstructionID MOCI = CandidateInfo.value ();
3066- switch (MOCI) {
3067- case MachineOutlinerDefault:
3068- // call t0, function = 8 bytes.
3069- CallOverhead = 8 ;
3070- // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3071- FrameOverhead = InstrSizeCExt;
3072- break ;
3073- case MachineOutlinerTailCall:
3059+ MachineOutlinerConstructionID MOCI = MachineOutlinerDefault;
3060+ if (Candidate.back ().isReturn ()) {
3061+ MOCI = MachineOutlinerTailCall;
30743062 // tail call = auipc + jalr in the worst case without linker relaxation.
30753063 CallOverhead = 4 + InstrSizeCExt;
30763064 // Using tail call we move ret instruction from caller to callee.
30773065 FrameOverhead = 0 ;
3078- break ;
3066+ } else {
3067+ // call t0, function = 8 bytes.
3068+ CallOverhead = 8 ;
3069+ // jr t0 = 4 bytes, 2 bytes if compressed instructions are enabled.
3070+ FrameOverhead = InstrSizeCExt;
30793071 }
30803072
30813073 for (auto &C : RepeatedSequenceLocs)
0 commit comments