@@ -610,26 +610,74 @@ static MCCFIInstruction createDefCFAOffset(const TargetRegisterInfo &TRI,
610610 Comment.str ());
611611}
612612
613+ // Allocate stack space and probe it if necessary.
613614void RISCVFrameLowering::allocateStack (MachineBasicBlock &MBB,
614615 MachineBasicBlock::iterator MBBI,
615- MachineFunction &MF, StackOffset Offset,
616- uint64_t RealStackSize,
617- bool EmitCFI) const {
616+ MachineFunction &MF, uint64_t Offset,
617+ uint64_t RealStackSize, bool EmitCFI,
618+ bool NeedProbe,
619+ uint64_t ProbeSize) const {
618620 DebugLoc DL;
619621 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
620622 const RISCVInstrInfo *TII = STI.getInstrInfo ();
621623
622- RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, Offset, MachineInstr::FrameSetup,
623- getStackAlign ());
624+ // Simply allocate the stack if it's not big enough to require a probe.
625+ if (!NeedProbe || Offset <= ProbeSize) {
626+ RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (-Offset),
627+ MachineInstr::FrameSetup, getStackAlign ());
624628
625- if (EmitCFI) {
626- // Emit ".cfi_def_cfa_offset RealStackSize"
627- unsigned CFIIndex = MF.addFrameInst (
628- MCCFIInstruction::cfiDefCfaOffset (nullptr , RealStackSize));
629- BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
630- .addCFIIndex (CFIIndex)
631- .setMIFlag (MachineInstr::FrameSetup);
629+ if (EmitCFI) {
630+ // Emit ".cfi_def_cfa_offset RealStackSize"
631+ unsigned CFIIndex = MF.addFrameInst (
632+ MCCFIInstruction::cfiDefCfaOffset (nullptr , RealStackSize));
633+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
634+ .addCFIIndex (CFIIndex)
635+ .setMIFlag (MachineInstr::FrameSetup);
636+ }
637+
638+ return ;
632639 }
640+
641+ // Do an unrolled probe loop.
642+ uint64_t CurrentOffset = 0 ;
643+ bool IsRV64 = STI.is64Bit ();
644+ while (CurrentOffset + ProbeSize <= Offset) {
645+ RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg,
646+ StackOffset::getFixed (-ProbeSize), MachineInstr::FrameSetup,
647+ getStackAlign ());
648+ // s[d|w] zero, 0(sp)
649+ BuildMI (MBB, MBBI, DL, TII->get (IsRV64 ? RISCV::SD : RISCV::SW))
650+ .addReg (RISCV::X0)
651+ .addReg (SPReg)
652+ .addImm (0 )
653+ .setMIFlags (MachineInstr::FrameSetup);
654+
655+ CurrentOffset += ProbeSize;
656+ if (EmitCFI) {
657+ // Emit ".cfi_def_cfa_offset CurrentOffset"
658+ unsigned CFIIndex = MF.addFrameInst (
659+ MCCFIInstruction::cfiDefCfaOffset (nullptr , CurrentOffset));
660+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
661+ .addCFIIndex (CFIIndex)
662+ .setMIFlag (MachineInstr::FrameSetup);
663+ }
664+ }
665+
666+ uint64_t Residual = Offset - CurrentOffset;
667+ if (Residual) {
668+ RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (-Residual),
669+ MachineInstr::FrameSetup, getStackAlign ());
670+ if (EmitCFI) {
671+ // Emit ".cfi_def_cfa_offset Offset"
672+ unsigned CFIIndex =
673+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , Offset));
674+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
675+ .addCFIIndex (CFIIndex)
676+ .setMIFlag (MachineInstr::FrameSetup);
677+ }
678+ }
679+
680+ return ;
633681}
634682
635683void RISCVFrameLowering::emitPrologue (MachineFunction &MF,
@@ -746,11 +794,14 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
746794 getPushOrLibCallsSavedInfo (MF, CSI));
747795 }
748796
749- if (StackSize != 0 ) {
750- // Allocate space on the stack if necessary.
751- allocateStack (MBB, MBBI, MF, StackOffset::getFixed (-StackSize),
752- RealStackSize, /* EmitCFI=*/ true );
753- }
797+ // Allocate space on the stack if necessary.
798+ auto &Subtarget = MF.getSubtarget <RISCVSubtarget>();
799+ const RISCVTargetLowering *TLI = Subtarget.getTargetLowering ();
800+ bool NeedProbe = TLI->hasInlineStackProbe (MF);
801+ uint64_t ProbeSize = TLI->getStackProbeSize (MF, getStackAlign ());
802+ if (StackSize != 0 )
803+ allocateStack (MBB, MBBI, MF, StackSize, RealStackSize, /* EmitCFI=*/ true ,
804+ NeedProbe, ProbeSize);
754805
755806 // The frame pointer is callee-saved, and code has been generated for us to
756807 // save it to the stack. We need to skip over the storing of callee-saved
@@ -791,8 +842,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
791842 assert (SecondSPAdjustAmount > 0 &&
792843 " SecondSPAdjustAmount should be greater than zero" );
793844
794- allocateStack (MBB, MBBI, MF, StackOffset::getFixed (-SecondSPAdjustAmount),
795- getStackSizeWithRVVPadding (MF), !hasFP (MF));
845+ allocateStack (MBB, MBBI, MF, SecondSPAdjustAmount,
846+ getStackSizeWithRVVPadding (MF), !hasFP (MF), NeedProbe,
847+ ProbeSize);
796848 }
797849
798850 if (RVVStackSize) {
0 commit comments