Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spill/restore FP/BP around instructions in which they are clobbered #81048

Merged
merged 8 commits into from
Aug 6, 2024
Merged
4 changes: 4 additions & 0 deletions llvm/include/llvm/CodeGen/TargetFrameLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,10 @@ class TargetFrameLowering {
/// Return the frame base information to be encoded in the DWARF subprogram
/// debug info.
virtual DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const;

/// If frame pointer or base pointer is clobbered by an instruction, we should
/// spill/restore it around that instruction.
virtual void spillFPBP(MachineFunction &MF) const {}
};

} // End llvm namespace
Expand Down
29 changes: 23 additions & 6 deletions llvm/lib/CodeGen/CFIInstrInserter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@ void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
unsigned NumRegs = TRI.getNumSupportedRegs(*MF);
BitVector CSRSaved(NumRegs), CSRRestored(NumRegs);

#ifndef NDEBUG
int RememberState = 0;
#endif

// Determine cfa offset and register set by the block.
for (MachineInstr &MI : *MBBInfo.MBB) {
if (MI.isCFIInstruction()) {
Expand Down Expand Up @@ -228,17 +232,23 @@ void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
case MCCFIInstruction::OpRememberState:
// TODO: Add support for handling cfi_remember_state.
#ifndef NDEBUG
report_fatal_error(
"Support for cfi_remember_state not implemented! Value of CFA "
"may be incorrect!\n");
// Currently we need cfi_remember_state and cfi_restore_state to be in
// the same BB, so it will not impact outgoing CFA.
++RememberState;
if (RememberState != 1)
report_fatal_error(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is existing code, but I generally try to recommend MCContext::reportError over report_fatal_error. We do have actual non-fatal error handling facilities during CodeGen.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

"Support for cfi_remember_state not implemented! Value of CFA "
"may be incorrect!\n");
#endif
break;
case MCCFIInstruction::OpRestoreState:
// TODO: Add support for handling cfi_restore_state.
#ifndef NDEBUG
report_fatal_error(
"Support for cfi_restore_state not implemented! Value of CFA may "
"be incorrect!\n");
--RememberState;
if (RememberState != 0)
report_fatal_error(
"Support for cfi_restore_state not implemented! Value of CFA may "
"be incorrect!\n");
#endif
break;
// Other CFI directives do not affect CFA value.
Expand All @@ -264,6 +274,13 @@ void CFIInstrInserter::calculateOutgoingCFAInfo(MBBCFAInfo &MBBInfo) {
}
}

#ifndef NDEBUG
if (RememberState != 0)
report_fatal_error(
"Support for cfi_remember_state not implemented! Value of CFA "
"may be incorrect!\n");
#endif

MBBInfo.Processed = true;

// Update outgoing CFA info.
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/CodeGen/PrologEpilogInserter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) {
FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(MF);
ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();

// Spill frame pointer and/or base pointer registers if they are clobbered.
// It is placed before call frame instruction elimination so it will not mess
// with stack arguments.
TFI->spillFPBP(MF);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PEI process is very complicated, please add comments elaborating on what this does and why it comes before call frame instruction elimination.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


// Calculate the MaxCallFrameSize value for the function's frame
// information. Also eliminates call frame pseudo instructions.
calculateCallFrameInfo(MF);
Expand Down
Loading
Loading