Skip to content

Commit e534981

Browse files
committed
[RISCV] Guard CFI emission code with MF.needsFrameMoves()
Currently, AsmPrinter skips CFI instructions if they are not needed. I'd like to change that so that it prints/encodes CFI instructions unconditionally. If a backend doesn't want them to be printed/encoded, it shouldn't create them. Apart from that, this change should slightly improve compile time as post-PEI passes no longer need to skip over these instructions in no-exceptions no-debug builds. The changes in a test seem to be caused by slightly different post-RA scheduling in the absence of CFI instructions.
1 parent ed9bcb5 commit e534981

File tree

2 files changed

+79
-52
lines changed

2 files changed

+79
-52
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 67 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ static const std::pair<MCPhysReg, int8_t> FixedCSRFIQCIInterruptMap[] = {
9292
/* -21, -22, -23, -24 are reserved */
9393
};
9494

95+
/// Returns true if DWARF CFI instructions ("frame moves") should be emitted.
96+
static bool needsDwarfCFI(const MachineFunction &MF) {
97+
return MF.needsFrameMoves();
98+
}
99+
95100
// For now we use x3, a.k.a gp, as pointer to shadow call stack.
96101
// User should not use x3 in their asm.
97102
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
@@ -138,6 +143,9 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
138143
.addImm(-SlotSize)
139144
.setMIFlag(MachineInstr::FrameSetup);
140145

146+
if (!needsDwarfCFI(MF))
147+
return;
148+
141149
// Emit a CFI instruction that causes SlotSize to be subtracted from the value
142150
// of the shadow stack pointer when unwinding past this frame.
143151
char DwarfSCSReg = TRI->getDwarfRegNum(SCSPReg, /*IsEH*/ true);
@@ -196,8 +204,10 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
196204
.addReg(SCSPReg)
197205
.addImm(-SlotSize)
198206
.setMIFlag(MachineInstr::FrameDestroy);
199-
// Restore the SCS pointer
200-
CFIInstBuilder(MBB, MI, MachineInstr::FrameDestroy).buildRestore(SCSPReg);
207+
if (needsDwarfCFI(MF)) {
208+
// Restore the SCS pointer
209+
CFIInstBuilder(MBB, MI, MachineInstr::FrameDestroy).buildRestore(SCSPReg);
210+
}
201211
}
202212

203213
// Get the ID of the libcall used for spilling and restoring callee saved
@@ -782,6 +792,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
782792
MBBI = std::prev(MBBI, getRVVCalleeSavedInfo(MF, CSI).size() +
783793
getUnmanagedCSI(MF, CSI).size());
784794
CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameSetup);
795+
bool NeedsDwarfCFI = needsDwarfCFI(MF);
785796

786797
// If libcalls are used to spill and restore callee-saved registers, the frame
787798
// has two sections; the opaque section managed by the libcalls, and the
@@ -809,10 +820,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
809820
alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
810821
RVFI->setLibCallStackSize(LibCallFrameSize);
811822

812-
CFIBuilder.buildDefCFAOffset(LibCallFrameSize);
813-
for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
814-
CFIBuilder.buildOffset(CS.getReg(),
815-
MFI.getObjectOffset(CS.getFrameIdx()));
823+
if (NeedsDwarfCFI) {
824+
CFIBuilder.buildDefCFAOffset(LibCallFrameSize);
825+
for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
826+
CFIBuilder.buildOffset(CS.getReg(),
827+
MFI.getObjectOffset(CS.getFrameIdx()));
828+
}
816829
}
817830

818831
// FIXME (note copied from Lanai): This appears to be overallocating. Needs
@@ -839,10 +852,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
839852
}
840853

841854
if (RVFI->useQCIInterrupt(MF)) {
842-
CFIBuilder.buildDefCFAOffset(QCIInterruptPushAmount);
843-
for (const CalleeSavedInfo &CS : getQCISavedInfo(MF, CSI))
844-
CFIBuilder.buildOffset(CS.getReg(),
845-
MFI.getObjectOffset(CS.getFrameIdx()));
855+
if (NeedsDwarfCFI) {
856+
CFIBuilder.buildDefCFAOffset(QCIInterruptPushAmount);
857+
for (const CalleeSavedInfo &CS : getQCISavedInfo(MF, CSI))
858+
CFIBuilder.buildOffset(CS.getReg(),
859+
MFI.getObjectOffset(CS.getFrameIdx()));
860+
}
846861
} else if (RVFI->isPushable(MF) && FirstFrameSetup != MBB.end() &&
847862
isPush(FirstFrameSetup->getOpcode())) {
848863
// Use available stack adjustment in push instruction to allocate additional
@@ -854,10 +869,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
854869
FirstFrameSetup->getOperand(1).setImm(StackAdj);
855870
StackSize -= StackAdj;
856871

857-
CFIBuilder.buildDefCFAOffset(RealStackSize - StackSize);
858-
for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
859-
CFIBuilder.buildOffset(CS.getReg(),
860-
MFI.getObjectOffset(CS.getFrameIdx()));
872+
if (NeedsDwarfCFI) {
873+
CFIBuilder.buildDefCFAOffset(RealStackSize - StackSize);
874+
for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
875+
CFIBuilder.buildOffset(CS.getReg(),
876+
MFI.getObjectOffset(CS.getFrameIdx()));
877+
}
861878
}
862879

863880
// Allocate space on the stack if necessary.
@@ -868,7 +885,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
868885
bool DynAllocation =
869886
MF.getInfo<RISCVMachineFunctionInfo>()->hasDynamicAllocation();
870887
if (StackSize != 0)
871-
allocateStack(MBB, MBBI, MF, StackSize, RealStackSize, /*EmitCFI=*/true,
888+
allocateStack(MBB, MBBI, MF, StackSize, RealStackSize, NeedsDwarfCFI,
872889
NeedProbe, ProbeSize, DynAllocation);
873890

874891
// The frame pointer is callee-saved, and code has been generated for us to
@@ -882,8 +899,10 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
882899

883900
// Iterate over list of callee-saved registers and emit .cfi_offset
884901
// directives.
885-
for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI))
886-
CFIBuilder.buildOffset(CS.getReg(), MFI.getObjectOffset(CS.getFrameIdx()));
902+
if (NeedsDwarfCFI)
903+
for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI))
904+
CFIBuilder.buildOffset(CS.getReg(),
905+
MFI.getObjectOffset(CS.getFrameIdx()));
887906

888907
// Generate new FP.
889908
if (hasFP(MF)) {
@@ -902,7 +921,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
902921
MachineInstr::FrameSetup, getStackAlign());
903922
}
904923

905-
CFIBuilder.buildDefCFA(FPReg, RVFI->getVarArgsSaveSize());
924+
if (NeedsDwarfCFI)
925+
CFIBuilder.buildDefCFA(FPReg, RVFI->getVarArgsSaveSize());
906926
}
907927

908928
uint64_t SecondSPAdjustAmount = 0;
@@ -913,15 +933,15 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
913933
"SecondSPAdjustAmount should be greater than zero");
914934

915935
allocateStack(MBB, MBBI, MF, SecondSPAdjustAmount,
916-
getStackSizeWithRVVPadding(MF), !hasFP(MF), NeedProbe,
917-
ProbeSize, DynAllocation);
936+
getStackSizeWithRVVPadding(MF), NeedsDwarfCFI && !hasFP(MF),
937+
NeedProbe, ProbeSize, DynAllocation);
918938
}
919939

920940
if (RVVStackSize) {
921941
if (NeedProbe) {
922942
allocateAndProbeStackForRVV(MF, MBB, MBBI, DL, RVVStackSize,
923-
MachineInstr::FrameSetup, !hasFP(MF),
924-
DynAllocation);
943+
MachineInstr::FrameSetup,
944+
NeedsDwarfCFI && !hasFP(MF), DynAllocation);
925945
} else {
926946
// We must keep the stack pointer aligned through any intermediate
927947
// updates.
@@ -930,14 +950,15 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
930950
MachineInstr::FrameSetup, getStackAlign());
931951
}
932952

933-
if (!hasFP(MF)) {
953+
if (NeedsDwarfCFI && !hasFP(MF)) {
934954
// Emit .cfi_def_cfa_expression "sp + StackSize + RVVStackSize * vlenb".
935955
CFIBuilder.insertCFIInst(createDefCFAExpression(
936956
*RI, SPReg, getStackSizeWithRVVPadding(MF), RVVStackSize / 8));
937957
}
938958

939959
std::advance(MBBI, getRVVCalleeSavedInfo(MF, CSI).size());
940-
emitCalleeSavedRVVPrologCFI(MBB, MBBI, hasFP(MF));
960+
if (NeedsDwarfCFI)
961+
emitCalleeSavedRVVPrologCFI(MBB, MBBI, hasFP(MF));
941962
}
942963

943964
if (hasFP(MF)) {
@@ -1004,8 +1025,9 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
10041025
MachineInstr::FrameDestroy, getStackAlign());
10051026
StackSize = 0;
10061027

1007-
CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy)
1008-
.buildDefCFAOffset(CFAOffset);
1028+
if (needsDwarfCFI(MF))
1029+
CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy)
1030+
.buildDefCFAOffset(CFAOffset);
10091031
}
10101032

10111033
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
@@ -1045,6 +1067,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
10451067
std::next(MBBI, getRVVCalleeSavedInfo(MF, CSI).size());
10461068
CFIInstBuilder CFIBuilder(MBB, FirstScalarCSRRestoreInsn,
10471069
MachineInstr::FrameDestroy);
1070+
bool NeedsDwarfCFI = needsDwarfCFI(MF);
10481071

10491072
uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
10501073
uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
@@ -1065,10 +1088,11 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
10651088
StackOffset::getScalable(RVVStackSize),
10661089
MachineInstr::FrameDestroy, getStackAlign());
10671090

1068-
if (!hasFP(MF))
1069-
CFIBuilder.buildDefCFA(SPReg, RealStackSize);
1070-
1071-
emitCalleeSavedRVVEpilogCFI(MBB, FirstScalarCSRRestoreInsn);
1091+
if (NeedsDwarfCFI) {
1092+
if (!hasFP(MF))
1093+
CFIBuilder.buildDefCFA(SPReg, RealStackSize);
1094+
emitCalleeSavedRVVEpilogCFI(MBB, FirstScalarCSRRestoreInsn);
1095+
}
10721096
}
10731097

10741098
if (FirstSPAdjustAmount) {
@@ -1084,7 +1108,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
10841108
StackOffset::getFixed(SecondSPAdjustAmount),
10851109
MachineInstr::FrameDestroy, getStackAlign());
10861110

1087-
if (!hasFP(MF))
1111+
if (NeedsDwarfCFI && !hasFP(MF))
10881112
CFIBuilder.buildDefCFAOffset(FirstSPAdjustAmount);
10891113
}
10901114

@@ -1105,7 +1129,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
11051129
getStackAlign());
11061130
}
11071131

1108-
if (hasFP(MF))
1132+
if (NeedsDwarfCFI && hasFP(MF))
11091133
CFIBuilder.buildDefCFA(SPReg, RealStackSize);
11101134

11111135
// Skip to after the restores of scalar callee-saved registers
@@ -1128,8 +1152,9 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
11281152
}
11291153

11301154
// Recover callee-saved registers.
1131-
for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI))
1132-
CFIBuilder.buildRestore(CS.getReg());
1155+
if (NeedsDwarfCFI)
1156+
for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI))
1157+
CFIBuilder.buildRestore(CS.getReg());
11331158

11341159
if (RVFI->isPushable(MF) && MBBI != MBB.end() && isPop(MBBI->getOpcode())) {
11351160
// Use available stack adjustment in pop instruction to deallocate stack
@@ -1148,14 +1173,16 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
11481173
auto NextI = next_nodbg(MBBI, MBB.end());
11491174
if (NextI == MBB.end() || NextI->getOpcode() != RISCV::PseudoRET) {
11501175
++MBBI;
1151-
CFIBuilder.setInsertPoint(MBBI);
1176+
if (NeedsDwarfCFI) {
1177+
CFIBuilder.setInsertPoint(MBBI);
11521178

1153-
for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
1154-
CFIBuilder.buildRestore(CS.getReg());
1179+
for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
1180+
CFIBuilder.buildRestore(CS.getReg());
11551181

1156-
// Update CFA offset. After CM_POP SP should be equal to CFA, so CFA
1157-
// offset should be a zero.
1158-
CFIBuilder.buildDefCFAOffset(0);
1182+
// Update CFA offset. After CM_POP SP should be equal to CFA, so CFA
1183+
// offset should be a zero.
1184+
CFIBuilder.buildDefCFAOffset(0);
1185+
}
11591186
}
11601187
}
11611188

llvm/test/CodeGen/RISCV/short-forward-branch-opt.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -444,11 +444,11 @@ define void @sextw_removal_ccor(i1 %c, i32 signext %arg, i32 signext %arg1, i32
444444
; RV64SFB-LABEL: sextw_removal_ccor:
445445
; RV64SFB: # %bb.0: # %bb
446446
; RV64SFB-NEXT: addi sp, sp, -32
447-
; RV64SFB-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
448447
; RV64SFB-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
449-
; RV64SFB-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
450448
; RV64SFB-NEXT: mv s0, a3
449+
; RV64SFB-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
451450
; RV64SFB-NEXT: andi a0, a0, 1
451+
; RV64SFB-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
452452
; RV64SFB-NEXT: mv s1, a2
453453
; RV64SFB-NEXT: beqz a0, .LBB15_4
454454
; RV64SFB-NEXT: # %bb.3: # %bb
@@ -470,11 +470,11 @@ define void @sextw_removal_ccor(i1 %c, i32 signext %arg, i32 signext %arg1, i32
470470
; ZICOND-LABEL: sextw_removal_ccor:
471471
; ZICOND: # %bb.0: # %bb
472472
; ZICOND-NEXT: addi sp, sp, -32
473-
; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
474473
; ZICOND-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
475-
; ZICOND-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
476474
; ZICOND-NEXT: mv s0, a3
475+
; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
477476
; ZICOND-NEXT: andi a0, a0, 1
477+
; ZICOND-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
478478
; ZICOND-NEXT: mv s1, a2
479479
; ZICOND-NEXT: beqz a0, .LBB15_4
480480
; ZICOND-NEXT: # %bb.3: # %bb
@@ -496,11 +496,11 @@ define void @sextw_removal_ccor(i1 %c, i32 signext %arg, i32 signext %arg1, i32
496496
; RV32SFB-LABEL: sextw_removal_ccor:
497497
; RV32SFB: # %bb.0: # %bb
498498
; RV32SFB-NEXT: addi sp, sp, -16
499-
; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
500499
; RV32SFB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
501-
; RV32SFB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
502500
; RV32SFB-NEXT: mv s0, a3
501+
; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
503502
; RV32SFB-NEXT: andi a0, a0, 1
503+
; RV32SFB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
504504
; RV32SFB-NEXT: mv s1, a2
505505
; RV32SFB-NEXT: beqz a0, .LBB15_4
506506
; RV32SFB-NEXT: # %bb.3: # %bb
@@ -563,11 +563,11 @@ define void @sextw_removal_ccaddw(i1 %c, i32 signext %arg, i32 signext %arg1, i3
563563
; RV64SFB-LABEL: sextw_removal_ccaddw:
564564
; RV64SFB: # %bb.0: # %bb
565565
; RV64SFB-NEXT: addi sp, sp, -32
566-
; RV64SFB-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
567-
; RV64SFB-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
568566
; RV64SFB-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
569567
; RV64SFB-NEXT: mv s1, a1
568+
; RV64SFB-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
570569
; RV64SFB-NEXT: andi a0, a0, 1
570+
; RV64SFB-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
571571
; RV64SFB-NEXT: mv s0, a2
572572
; RV64SFB-NEXT: beqz a0, .LBB16_4
573573
; RV64SFB-NEXT: # %bb.3: # %bb
@@ -589,11 +589,11 @@ define void @sextw_removal_ccaddw(i1 %c, i32 signext %arg, i32 signext %arg1, i3
589589
; ZICOND-LABEL: sextw_removal_ccaddw:
590590
; ZICOND: # %bb.0: # %bb
591591
; ZICOND-NEXT: addi sp, sp, -32
592-
; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
593-
; ZICOND-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
594592
; ZICOND-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
595593
; ZICOND-NEXT: mv s1, a1
594+
; ZICOND-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
596595
; ZICOND-NEXT: andi a0, a0, 1
596+
; ZICOND-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
597597
; ZICOND-NEXT: mv s0, a2
598598
; ZICOND-NEXT: beqz a0, .LBB16_4
599599
; ZICOND-NEXT: # %bb.3: # %bb
@@ -615,11 +615,11 @@ define void @sextw_removal_ccaddw(i1 %c, i32 signext %arg, i32 signext %arg1, i3
615615
; RV32SFB-LABEL: sextw_removal_ccaddw:
616616
; RV32SFB: # %bb.0: # %bb
617617
; RV32SFB-NEXT: addi sp, sp, -16
618-
; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
619-
; RV32SFB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
620618
; RV32SFB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
621619
; RV32SFB-NEXT: mv s1, a1
620+
; RV32SFB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
622621
; RV32SFB-NEXT: andi a0, a0, 1
622+
; RV32SFB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
623623
; RV32SFB-NEXT: mv s0, a2
624624
; RV32SFB-NEXT: beqz a0, .LBB16_4
625625
; RV32SFB-NEXT: # %bb.3: # %bb

0 commit comments

Comments
 (0)