#ifndef LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H
#define LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Support/TypeSize.h"
namespace llvm {
class MachineInstrBuilder;
class MCCFIInstruction;
class X86InstrInfo;
class X86Subtarget;
class X86RegisterInfo;
class X86FrameLowering : public TargetFrameLowering {
public:
X86FrameLowering(const X86Subtarget &STI, MaybeAlign StackAlignOverride);
const X86Subtarget &STI;
const X86InstrInfo &TII;
const X86RegisterInfo *TRI;
unsigned SlotSize;
bool Is64Bit;
bool IsLP64;
bool Uses64BitFramePtr;
unsigned StackPtr;
void emitStackProbe(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog,
Optional<MachineFunction::DebugInstrOperandPair> InstrNum = None) const;
bool stackProbeFunctionModifiesSP() const override;
void inlineStackProbe(MachineFunction &MF,
MachineBasicBlock &PrologMBB) const override;
void emitCalleeSavedFrameMovesFullCFA(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override;
void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, bool IsPrologue) const;
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void adjustForSegmentedStacks(MachineFunction &MF,
MachineBasicBlock &PrologueMBB) const override;
void adjustForHiPEPrologue(MachineFunction &MF,
MachineBasicBlock &PrologueMBB) const override;
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS = nullptr) const override;
bool
assignCalleeSavedSpillSlots(MachineFunction &MF,
const TargetRegisterInfo *TRI,
std::vector<CalleeSavedInfo> &CSI) const override;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
ArrayRef<CalleeSavedInfo> CSI,
const TargetRegisterInfo *TRI) const override;
bool
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
MutableArrayRef<CalleeSavedInfo> CSI,
const TargetRegisterInfo *TRI) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
bool needsFrameIndexResolution(const MachineFunction &MF) const override;
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg) const override;
int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI,
Register &SPReg) const;
StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI,
Register &SPReg, int Adjustment) const;
StackOffset
getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
Register &FrameReg,
bool IgnoreSPUpdates) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS) const override;
void
processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF,
RegScavenger *RS) const override;
int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
bool doMergeWithPrevious) const;
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
const DebugLoc &DL, int64_t NumBytes, bool InEpilogue) const;
bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const;
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
bool enableShrinkWrapping(const MachineFunction &MF) const override;
void orderFrameObjects(const MachineFunction &MF,
SmallVectorImpl<int> &ObjectsToAllocate) const override;
void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, const MCCFIInstruction &CFIInst,
MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
MachineBasicBlock::iterator
restoreWin32EHStackPointers(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, bool RestoreSP = false) const;
void restoreWinEHStackPointersInParent(MachineFunction &MF) const;
int getInitialCFAOffset(const MachineFunction &MF) const override;
Register getInitialCFARegister(const MachineFunction &MF) const override;
bool has128ByteRedZone(const MachineFunction& MF) const;
private:
bool isWin64Prologue(const MachineFunction &MF) const;
bool needsDwarfCFI(const MachineFunction &MF) const;
uint64_t calculateMaxStackAlign(const MachineFunction &MF) const;
void emitStackProbeCall(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog,
Optional<MachineFunction::DebugInstrOperandPair> InstrNum) const;
void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, bool InProlog) const;
void emitStackProbeInlineWindowsCoreCLR64(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL,
bool InProlog) const;
void emitStackProbeInlineGeneric(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, bool InProlog) const;
void emitStackProbeInlineGenericBlock(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, uint64_t Offset,
uint64_t Align) const;
void emitStackProbeInlineGenericLoop(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, uint64_t Offset,
uint64_t Align) const;
void emitZeroCallUsedRegs(BitVector RegsToZero,
MachineBasicBlock &MBB) const override;
void adjustFrameForMsvcCxxEh(MachineFunction &MF) const;
void BuildStackAlignAND(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
unsigned Reg, uint64_t MaxAlign) const;
bool adjustStackWithPops(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
int Offset) const;
MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL, int64_t Offset,
bool InEpilogue) const;
unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const;
unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;
void emitCatchRetReturnValue(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
MachineInstr *CatchRet) const;
};
}
#endif