11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " RISCVInstrInfo.h"
14
- #include " MCTargetDesc/RISCVBaseInfo.h"
15
14
#include " MCTargetDesc/RISCVMatInt.h"
16
15
#include " RISCV.h"
17
16
#include " RISCVMachineFunctionInfo.h"
@@ -2928,7 +2927,6 @@ bool RISCVInstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB,
2928
2927
2929
2928
// Enum values indicating how an outlined call should be constructed.
2930
2929
enum MachineOutlinerConstructionID {
2931
- MachineOutlinerTailCall,
2932
2930
MachineOutlinerDefault
2933
2931
};
2934
2932
@@ -2937,118 +2935,46 @@ bool RISCVInstrInfo::shouldOutlineFromFunctionByDefault(
2937
2935
return MF.getFunction ().hasMinSize ();
2938
2936
}
2939
2937
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
-
3006
2938
std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3007
2939
RISCVInstrInfo::getOutliningCandidateInfo (
3008
2940
const MachineModuleInfo &MMI,
3009
2941
std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3010
2942
unsigned MinRepeats) const {
3011
2943
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);
3017
2952
3018
2953
// If the sequence doesn't have enough candidates left, then we're done.
3019
2954
if (RepeatedSequenceLocs.size () < MinRepeats)
3020
2955
return std::nullopt;
3021
2956
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);
3042
2961
2962
+ // call t0, function = 8 bytes.
2963
+ unsigned CallOverhead = 8 ;
3043
2964
for (auto &C : RepeatedSequenceLocs)
3044
- C.setCallInfo (MOCI , CallOverhead);
2965
+ C.setCallInfo (MachineOutlinerDefault , CallOverhead);
3045
2966
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 ;
3049
2974
3050
2975
return std::make_unique<outliner::OutlinedFunction>(
3051
- RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
2976
+ RepeatedSequenceLocs, SequenceSize, FrameOverhead,
2977
+ MachineOutlinerDefault);
3052
2978
}
3053
2979
3054
2980
outliner::InstrType
@@ -3069,8 +2995,15 @@ RISCVInstrInfo::getOutliningTypeImpl(const MachineModuleInfo &MMI,
3069
2995
return F.needsUnwindTableEntry () ? outliner::InstrType::Illegal
3070
2996
: outliner::InstrType::Invisible;
3071
2997
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))
3074
3007
return outliner::InstrType::Illegal;
3075
3008
3076
3009
// Make sure the operands don't reference something unsafe.
@@ -3106,9 +3039,6 @@ void RISCVInstrInfo::buildOutlinedFrame(
3106
3039
}
3107
3040
}
3108
3041
3109
- if (OF.FrameConstructionID == MachineOutlinerTailCall)
3110
- return ;
3111
-
3112
3042
MBB.addLiveIn (RISCV::X5);
3113
3043
3114
3044
// Add in a return instruction to the end of the outlined frame.
@@ -3122,13 +3052,6 @@ MachineBasicBlock::iterator RISCVInstrInfo::insertOutlinedCall(
3122
3052
Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It,
3123
3053
MachineFunction &MF, outliner::Candidate &C) const {
3124
3054
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
-
3132
3055
// Add in a call instruction to the outlined function at the given location.
3133
3056
It = MBB.insert (It,
3134
3057
BuildMI (MF, DebugLoc (), get (RISCV::PseudoCALLReg), RISCV::X5)
0 commit comments