@@ -580,26 +580,74 @@ static MCCFIInstruction createDefCFAOffset(const TargetRegisterInfo &TRI,
580580 Comment.str ());
581581}
582582
583+ // Allocate stack space and probe it if necessary.
583584void RISCVFrameLowering::allocateStack (MachineBasicBlock &MBB,
584585 MachineBasicBlock::iterator MBBI,
585- MachineFunction &MF, StackOffset Offset,
586- uint64_t RealStackSize,
587- bool EmitCFI) const {
586+ MachineFunction &MF, uint64_t Offset,
587+ uint64_t RealStackSize, bool EmitCFI,
588+ bool NeedProbe,
589+ uint64_t ProbeSize) const {
588590 DebugLoc DL;
589591 const RISCVRegisterInfo *RI = STI.getRegisterInfo ();
590592 const RISCVInstrInfo *TII = STI.getInstrInfo ();
591593
592- RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, Offset, MachineInstr::FrameSetup,
593- getStackAlign ());
594+ // Simply allocate the stack if it's not big enough to require a probe.
595+ if (!NeedProbe || Offset <= ProbeSize) {
596+ RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (-Offset),
597+ MachineInstr::FrameSetup, getStackAlign ());
594598
595- if (EmitCFI) {
596- // Emit ".cfi_def_cfa_offset RealStackSize"
597- unsigned CFIIndex = MF.addFrameInst (
598- MCCFIInstruction::cfiDefCfaOffset (nullptr , RealStackSize));
599- BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
600- .addCFIIndex (CFIIndex)
601- .setMIFlag (MachineInstr::FrameSetup);
599+ if (EmitCFI) {
600+ // Emit ".cfi_def_cfa_offset RealStackSize"
601+ unsigned CFIIndex = MF.addFrameInst (
602+ MCCFIInstruction::cfiDefCfaOffset (nullptr , RealStackSize));
603+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
604+ .addCFIIndex (CFIIndex)
605+ .setMIFlag (MachineInstr::FrameSetup);
606+ }
607+
608+ return ;
602609 }
610+
611+ // Do an unrolled probe loop.
612+ uint64_t CurrentOffset = 0 ;
613+ bool IsRV64 = STI.is64Bit ();
614+ while (CurrentOffset + ProbeSize <= Offset) {
615+ RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg,
616+ StackOffset::getFixed (-ProbeSize), MachineInstr::FrameSetup,
617+ getStackAlign ());
618+ // s[d|w] zero, 0(sp)
619+ BuildMI (MBB, MBBI, DL, TII->get (IsRV64 ? RISCV::SD : RISCV::SW))
620+ .addReg (RISCV::X0)
621+ .addReg (SPReg)
622+ .addImm (0 )
623+ .setMIFlags (MachineInstr::FrameSetup);
624+
625+ CurrentOffset += ProbeSize;
626+ if (EmitCFI) {
627+ // Emit ".cfi_def_cfa_offset CurrentOffset"
628+ unsigned CFIIndex = MF.addFrameInst (
629+ MCCFIInstruction::cfiDefCfaOffset (nullptr , CurrentOffset));
630+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
631+ .addCFIIndex (CFIIndex)
632+ .setMIFlag (MachineInstr::FrameSetup);
633+ }
634+ }
635+
636+ uint64_t Residual = Offset - CurrentOffset;
637+ if (Residual) {
638+ RI->adjustReg (MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed (-Residual),
639+ MachineInstr::FrameSetup, getStackAlign ());
640+ if (EmitCFI) {
641+ // Emit ".cfi_def_cfa_offset Offset"
642+ unsigned CFIIndex =
643+ MF.addFrameInst (MCCFIInstruction::cfiDefCfaOffset (nullptr , Offset));
644+ BuildMI (MBB, MBBI, DL, TII->get (TargetOpcode::CFI_INSTRUCTION))
645+ .addCFIIndex (CFIIndex)
646+ .setMIFlag (MachineInstr::FrameSetup);
647+ }
648+ }
649+
650+ return ;
603651}
604652
605653void RISCVFrameLowering::emitPrologue (MachineFunction &MF,
@@ -716,11 +764,14 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
716764 getPushOrLibCallsSavedInfo (MF, CSI));
717765 }
718766
719- if (StackSize != 0 ) {
720- // Allocate space on the stack if necessary.
721- allocateStack (MBB, MBBI, MF, StackOffset::getFixed (-StackSize),
722- RealStackSize, /* EmitCFI=*/ true );
723- }
767+ // Allocate space on the stack if necessary.
768+ auto &Subtarget = MF.getSubtarget <RISCVSubtarget>();
769+ const RISCVTargetLowering *TLI = Subtarget.getTargetLowering ();
770+ bool NeedProbe = TLI->hasInlineStackProbe (MF);
771+ uint64_t ProbeSize = TLI->getStackProbeSize (MF, getStackAlign ());
772+ if (StackSize != 0 )
773+ allocateStack (MBB, MBBI, MF, StackSize, RealStackSize, /* EmitCFI=*/ true ,
774+ NeedProbe, ProbeSize);
724775
725776 // The frame pointer is callee-saved, and code has been generated for us to
726777 // save it to the stack. We need to skip over the storing of callee-saved
@@ -761,8 +812,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
761812 assert (SecondSPAdjustAmount > 0 &&
762813 " SecondSPAdjustAmount should be greater than zero" );
763814
764- allocateStack (MBB, MBBI, MF, StackOffset::getFixed (-SecondSPAdjustAmount),
765- getStackSizeWithRVVPadding (MF), !hasFP (MF));
815+ allocateStack (MBB, MBBI, MF, SecondSPAdjustAmount,
816+ getStackSizeWithRVVPadding (MF), !hasFP (MF), NeedProbe,
817+ ProbeSize);
766818 }
767819
768820 if (RVVStackSize) {
0 commit comments