@@ -608,23 +608,37 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
608
608
int64_t RDXShadowSlot = 0 ;
609
609
610
610
// If inlining in the prolog, save RCX and RDX.
611
- // Future optimization: don't save or restore if not live in.
612
611
if (InProlog) {
613
612
// Compute the offsets. We need to account for things already
614
613
// pushed onto the stack at this point: return address, frame
615
614
// pointer (if used), and callee saves.
616
615
X86MachineFunctionInfo *X86FI = MF.getInfo <X86MachineFunctionInfo>();
617
616
const int64_t CalleeSaveSize = X86FI->getCalleeSavedFrameSize ();
618
617
const bool HasFP = hasFP (MF);
619
- RCXShadowSlot = 8 + CalleeSaveSize + (HasFP ? 8 : 0 );
620
- RDXShadowSlot = RCXShadowSlot + 8 ;
621
- // Emit the saves.
622
- addRegOffset (BuildMI (&MBB, DL, TII.get (X86::MOV64mr)), X86::RSP, false ,
623
- RCXShadowSlot)
624
- .addReg (X86::RCX);
625
- addRegOffset (BuildMI (&MBB, DL, TII.get (X86::MOV64mr)), X86::RSP, false ,
626
- RDXShadowSlot)
627
- .addReg (X86::RDX);
618
+
619
+ // Check if we need to spill RCX and/or RDX.
620
+ // Here we assume that no earlier prologue instruction changes RCX and/or
621
+ // RDX, so checking the block live-ins is enough.
622
+ const bool IsRCXLiveIn = MBB.isLiveIn (X86::RCX);
623
+ const bool IsRDXLiveIn = MBB.isLiveIn (X86::RDX);
624
+ int64_t InitSlot = 8 + CalleeSaveSize + (HasFP ? 8 : 0 );
625
+ // Assign the initial slot to both registers, then change RDX's slot if both
626
+ // need to be spilled.
627
+ if (IsRCXLiveIn)
628
+ RCXShadowSlot = InitSlot;
629
+ if (IsRDXLiveIn)
630
+ RDXShadowSlot = InitSlot;
631
+ if (IsRDXLiveIn && IsRCXLiveIn)
632
+ RDXShadowSlot += 8 ;
633
+ // Emit the saves if needed.
634
+ if (IsRCXLiveIn)
635
+ addRegOffset (BuildMI (&MBB, DL, TII.get (X86::MOV64mr)), X86::RSP, false ,
636
+ RCXShadowSlot)
637
+ .addReg (X86::RCX);
638
+ if (IsRDXLiveIn)
639
+ addRegOffset (BuildMI (&MBB, DL, TII.get (X86::MOV64mr)), X86::RSP, false ,
640
+ RDXShadowSlot)
641
+ .addReg (X86::RDX);
628
642
} else {
629
643
// Not in the prolog. Copy RAX to a virtual reg.
630
644
BuildMI (&MBB, DL, TII.get (X86::MOV64rr), SizeReg).addReg (X86::RAX);
@@ -661,6 +675,7 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
661
675
BuildMI (&MBB, DL, TII.get (X86::JAE_1)).addMBB (ContinueMBB);
662
676
663
677
// Add code to roundMBB to round the final stack pointer to a page boundary.
678
+ RoundMBB->addLiveIn (FinalReg);
664
679
BuildMI (RoundMBB, DL, TII.get (X86::AND64ri32), RoundedReg)
665
680
.addReg (FinalReg)
666
681
.addImm (PageMask);
@@ -677,6 +692,7 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
677
692
.addMBB (LoopMBB);
678
693
}
679
694
695
+ LoopMBB->addLiveIn (JoinReg);
680
696
addRegOffset (BuildMI (LoopMBB, DL, TII.get (X86::LEA64r), ProbeReg), JoinReg,
681
697
false , -PageSize);
682
698
@@ -688,6 +704,8 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
688
704
.addImm (0 )
689
705
.addReg (0 )
690
706
.addImm (0 );
707
+
708
+ LoopMBB->addLiveIn (RoundedReg);
691
709
BuildMI (LoopMBB, DL, TII.get (X86::CMP64rr))
692
710
.addReg (RoundedReg)
693
711
.addReg (ProbeReg);
@@ -697,16 +715,19 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
697
715
698
716
// If in prolog, restore RDX and RCX.
699
717
if (InProlog) {
700
- addRegOffset (BuildMI (*ContinueMBB, ContinueMBBI, DL, TII.get (X86::MOV64rm),
701
- X86::RCX),
702
- X86::RSP, false , RCXShadowSlot);
703
- addRegOffset (BuildMI (*ContinueMBB, ContinueMBBI, DL, TII.get (X86::MOV64rm),
704
- X86::RDX),
705
- X86::RSP, false , RDXShadowSlot);
718
+ if (RCXShadowSlot) // It means we spilled RCX in the prologue.
719
+ addRegOffset (BuildMI (*ContinueMBB, ContinueMBBI, DL,
720
+ TII.get (X86::MOV64rm), X86::RCX),
721
+ X86::RSP, false , RCXShadowSlot);
722
+ if (RDXShadowSlot) // It means we spilled RDX in the prologue.
723
+ addRegOffset (BuildMI (*ContinueMBB, ContinueMBBI, DL,
724
+ TII.get (X86::MOV64rm), X86::RDX),
725
+ X86::RSP, false , RDXShadowSlot);
706
726
}
707
727
708
728
// Now that the probing is done, add code to continueMBB to update
709
729
// the stack pointer for real.
730
+ ContinueMBB->addLiveIn (SizeReg);
710
731
BuildMI (*ContinueMBB, ContinueMBBI, DL, TII.get (X86::SUB64rr), X86::RSP)
711
732
.addReg (X86::RSP)
712
733
.addReg (SizeReg);
@@ -734,8 +755,6 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
734
755
CMBBI->setFlag (MachineInstr::FrameSetup);
735
756
}
736
757
}
737
-
738
- // Possible TODO: physreg liveness for InProlog case.
739
758
}
740
759
741
760
void X86FrameLowering::emitStackProbeCall (MachineFunction &MF,
0 commit comments