Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
lib/Target/X86/X86FrameLowering.cpp
Show First 20 Lines • Show All 1,539 Lines • ▼ Show 20 Lines | void X86FrameLowering::emitEpilogue(MachineFunction &MF, | ||||
// Get the number of bytes to allocate from the FrameInfo. | // Get the number of bytes to allocate from the FrameInfo. | ||||
uint64_t StackSize = MFI.getStackSize(); | uint64_t StackSize = MFI.getStackSize(); | ||||
uint64_t MaxAlign = calculateMaxStackAlign(MF); | uint64_t MaxAlign = calculateMaxStackAlign(MF); | ||||
unsigned CSSize = X86FI->getCalleeSavedFrameSize(); | unsigned CSSize = X86FI->getCalleeSavedFrameSize(); | ||||
bool HasFP = hasFP(MF); | bool HasFP = hasFP(MF); | ||||
uint64_t NumBytes = 0; | uint64_t NumBytes = 0; | ||||
bool NeedsDwarfCFI = | |||||
(!MF.getTarget().getTargetTriple().isOSDarwin() && | |||||
!MF.getTarget().getTargetTriple().isOSWindows()) && | |||||
(MF.getMMI().hasDebugInfo() || MF.getFunction()->needsUnwindTableEntry()); | |||||
if (IsFunclet) { | if (IsFunclet) { | ||||
assert(HasFP && "EH funclets without FP not yet implemented"); | assert(HasFP && "EH funclets without FP not yet implemented"); | ||||
NumBytes = getWinEHFuncletFrameSize(MF); | NumBytes = getWinEHFuncletFrameSize(MF); | ||||
} else if (HasFP) { | } else if (HasFP) { | ||||
// Calculate required stack adjustment. | // Calculate required stack adjustment. | ||||
uint64_t FrameSize = StackSize - SlotSize; | uint64_t FrameSize = StackSize - SlotSize; | ||||
NumBytes = FrameSize - CSSize; | NumBytes = FrameSize - CSSize; | ||||
// Callee-saved registers were pushed on stack before the stack was | // Callee-saved registers were pushed on stack before the stack was | ||||
// realigned. | // realigned. | ||||
if (TRI->needsStackRealignment(MF) && !IsWin64Prologue) | if (TRI->needsStackRealignment(MF) && !IsWin64Prologue) | ||||
NumBytes = alignTo(FrameSize, MaxAlign); | NumBytes = alignTo(FrameSize, MaxAlign); | ||||
} else { | } else { | ||||
NumBytes = StackSize - CSSize; | NumBytes = StackSize - CSSize; | ||||
} | } | ||||
uint64_t SEHStackAllocAmt = NumBytes; | uint64_t SEHStackAllocAmt = NumBytes; | ||||
if (HasFP) { | if (HasFP) { | ||||
// Pop EBP. | // Pop EBP. | ||||
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), | BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), | ||||
MachineFramePtr) | MachineFramePtr) | ||||
.setMIFlag(MachineInstr::FrameDestroy); | .setMIFlag(MachineInstr::FrameDestroy); | ||||
if (NeedsDwarfCFI) { | |||||
unsigned DwarfStackPtr = | |||||
TRI->getDwarfRegNum(Is64Bit ? X86::RSP : X86::ESP, true); | |||||
BuildCFI(MBB, MBBI, DL, MCCFIInstruction::createDefCfa( | |||||
nullptr, DwarfStackPtr, -SlotSize)); | |||||
--MBBI; | |||||
} | |||||
} | } | ||||
MachineBasicBlock::iterator FirstCSPop = MBBI; | MachineBasicBlock::iterator FirstCSPop = MBBI; | ||||
// Skip the callee-saved pop instructions. | // Skip the callee-saved pop instructions. | ||||
while (MBBI != MBB.begin()) { | while (MBBI != MBB.begin()) { | ||||
MachineBasicBlock::iterator PI = std::prev(MBBI); | MachineBasicBlock::iterator PI = std::prev(MBBI); | ||||
unsigned Opc = PI->getOpcode(); | unsigned Opc = PI->getOpcode(); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | if (LEAAmount != 0) { | ||||
unsigned Opc = (Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr); | unsigned Opc = (Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr); | ||||
BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) | BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) | ||||
.addReg(FramePtr); | .addReg(FramePtr); | ||||
--MBBI; | --MBBI; | ||||
} | } | ||||
} else if (NumBytes) { | } else if (NumBytes) { | ||||
// Adjust stack pointer back: ESP += numbytes. | // Adjust stack pointer back: ESP += numbytes. | ||||
emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true); | emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true); | ||||
if (!hasFP(MF) && NeedsDwarfCFI) { | |||||
// Define the current CFA rule to use the provided offset. | |||||
BuildCFI(MBB, MBBI, DL, MCCFIInstruction::createDefCfaOffset( | |||||
nullptr, -CSSize - SlotSize)); | |||||
} | |||||
--MBBI; | --MBBI; | ||||
} | } | ||||
// Windows unwinder will not invoke function's exception handler if IP is | // Windows unwinder will not invoke function's exception handler if IP is | ||||
// either in prologue or in epilogue. This behavior causes a problem when a | // either in prologue or in epilogue. This behavior causes a problem when a | ||||
// call immediately precedes an epilogue, because the return address points | // call immediately precedes an epilogue, because the return address points | ||||
// into the epilogue. To cope with that, we insert an epilogue marker here, | // into the epilogue. To cope with that, we insert an epilogue marker here, | ||||
// then replace it with a 'nop' if it ends up immediately after a CALL in the | // then replace it with a 'nop' if it ends up immediately after a CALL in the | ||||
// final emitted code. | // final emitted code. | ||||
if (NeedsWinCFI && MF.hasWinCFI()) | if (NeedsWinCFI && MF.hasWinCFI()) | ||||
BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_Epilogue)); | BuildMI(MBB, MBBI, DL, TII.get(X86::SEH_Epilogue)); | ||||
if (!hasFP(MF) && NeedsDwarfCFI) { | |||||
MBBI = FirstCSPop; | |||||
int64_t Offset = -CSSize - SlotSize; | |||||
// Mark callee-saved pop instruction. | |||||
// Define the current CFA rule to use the provided offset. | |||||
while (MBBI != MBB.end()) { | |||||
MachineBasicBlock::iterator PI = MBBI; | |||||
unsigned Opc = PI->getOpcode(); | |||||
++MBBI; | |||||
if (Opc == X86::POP32r || Opc == X86::POP64r) { | |||||
Offset += SlotSize; | |||||
BuildCFI(MBB, MBBI, DL, | |||||
MCCFIInstruction::createDefCfaOffset(nullptr, Offset)); | |||||
} | |||||
} | |||||
} | |||||
if (Terminator == MBB.end() || !isTailCallOpcode(Terminator->getOpcode())) { | if (Terminator == MBB.end() || !isTailCallOpcode(Terminator->getOpcode())) { | ||||
// Add the return addr area delta back since we are not tail calling. | // Add the return addr area delta back since we are not tail calling. | ||||
int Offset = -1 * X86FI->getTCReturnAddrDelta(); | int Offset = -1 * X86FI->getTCReturnAddrDelta(); | ||||
assert(Offset >= 0 && "TCDelta should never be positive"); | assert(Offset >= 0 && "TCDelta should never be positive"); | ||||
if (Offset) { | if (Offset) { | ||||
// Check for possible merge with preceding ADD instruction. | // Check for possible merge with preceding ADD instruction. | ||||
Offset += mergeSPUpdates(MBB, Terminator, true); | Offset += mergeSPUpdates(MBB, Terminator, true); | ||||
emitSPUpdate(MBB, Terminator, Offset, /*InEpilogue=*/true); | emitSPUpdate(MBB, Terminator, Offset, /*InEpilogue=*/true); | ||||
▲ Show 20 Lines • Show All 1,160 Lines • ▼ Show 20 Lines | addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32rm), FramePtr), | ||||
UsedReg, true, Offset) | UsedReg, true, Offset) | ||||
.setMIFlag(MachineInstr::FrameSetup); | .setMIFlag(MachineInstr::FrameSetup); | ||||
} else { | } else { | ||||
llvm_unreachable("32-bit frames with WinEH must use FramePtr or BasePtr"); | llvm_unreachable("32-bit frames with WinEH must use FramePtr or BasePtr"); | ||||
} | } | ||||
return MBBI; | return MBBI; | ||||
} | } | ||||
int X86FrameLowering::getInitialCFAOffset(const MachineFunction &MF) const { | |||||
return TRI->getSlotSize(); | |||||
} | |||||
unsigned X86FrameLowering::getInitialCFARegister(const MachineFunction &MF) | |||||
const { | |||||
return TRI->getDwarfRegNum(StackPtr, true); | |||||
} | |||||
namespace { | namespace { | ||||
// Struct used by orderFrameObjects to help sort the stack objects. | // Struct used by orderFrameObjects to help sort the stack objects. | ||||
struct X86FrameSortingObject { | struct X86FrameSortingObject { | ||||
bool IsValid = false; // true if we care about this Object. | bool IsValid = false; // true if we care about this Object. | ||||
unsigned ObjectIndex = 0; // Index of Object into MFI list. | unsigned ObjectIndex = 0; // Index of Object into MFI list. | ||||
unsigned ObjectSize = 0; // Size of Object in bytes. | unsigned ObjectSize = 0; // Size of Object in bytes. | ||||
unsigned ObjectAlignment = 1; // Alignment of Object in bytes. | unsigned ObjectAlignment = 1; // Alignment of Object in bytes. | ||||
unsigned ObjectNumUses = 0; // Object static number of uses. | unsigned ObjectNumUses = 0; // Object static number of uses. | ||||
▲ Show 20 Lines • Show All 204 Lines • Show Last 20 Lines |