Path: blob/main/contrib/llvm-project/llvm/lib/Target/X86/X86FrameLowering.h
35268 views
//===-- X86TargetFrameLowering.h - Define frame lowering for X86 -*- C++ -*-==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This class implements X86-specific bits of TargetFrameLowering class.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H13#define LLVM_LIB_TARGET_X86_X86FRAMELOWERING_H1415#include "llvm/CodeGen/MachineFunction.h"16#include "llvm/CodeGen/TargetFrameLowering.h"17#include "llvm/Support/TypeSize.h"1819namespace llvm {2021class MachineInstrBuilder;22class MCCFIInstruction;23class X86InstrInfo;24class X86Subtarget;25class X86RegisterInfo;2627class X86FrameLowering : public TargetFrameLowering {28public:29X86FrameLowering(const X86Subtarget &STI, MaybeAlign StackAlignOverride);3031// Cached subtarget predicates.3233const X86Subtarget &STI;34const X86InstrInfo &TII;35const X86RegisterInfo *TRI;3637unsigned SlotSize;3839/// Is64Bit implies that x86_64 instructions are available.40bool Is64Bit;4142bool IsLP64;4344/// True if the 64-bit frame or stack pointer should be used. True for most45/// 64-bit targets with the exception of x32. If this is false, 32-bit46/// instruction operands should be used to manipulate StackPtr and FramePtr.47bool Uses64BitFramePtr;4849unsigned StackPtr;5051/// Emit target stack probe code. This is required for all52/// large stack allocations on Windows. The caller is required to materialize53/// the number of bytes to probe in RAX/EAX.54/// \p InstrNum optionally contains a debug-info instruction number for the55/// new stack pointer.56void emitStackProbe(MachineFunction &MF, MachineBasicBlock &MBB,57MachineBasicBlock::iterator MBBI, const DebugLoc &DL,58bool InProlog,59std::optional<MachineFunction::DebugInstrOperandPair>60InstrNum = std::nullopt) const;6162bool stackProbeFunctionModifiesSP() const override;6364/// Replace a StackProbe inline-stub with the actual probe code inline.65void inlineStackProbe(MachineFunction &MF,66MachineBasicBlock &PrologMBB) const override;6768void emitCalleeSavedFrameMovesFullCFA(69MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const override;7071void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,72MachineBasicBlock::iterator MBBI,73const DebugLoc &DL, bool IsPrologue) const;7475/// emitProlog/emitEpilog - These methods insert prolog and epilog code into76/// the function.77void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;78void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;7980void adjustForSegmentedStacks(MachineFunction &MF,81MachineBasicBlock &PrologueMBB) const override;8283void adjustForHiPEPrologue(MachineFunction &MF,84MachineBasicBlock &PrologueMBB) const override;8586void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,87RegScavenger *RS = nullptr) const override;8889bool90assignCalleeSavedSpillSlots(MachineFunction &MF,91const TargetRegisterInfo *TRI,92std::vector<CalleeSavedInfo> &CSI) const override;9394bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,95MachineBasicBlock::iterator MI,96ArrayRef<CalleeSavedInfo> CSI,97const TargetRegisterInfo *TRI) const override;9899bool100restoreCalleeSavedRegisters(MachineBasicBlock &MBB,101MachineBasicBlock::iterator MI,102MutableArrayRef<CalleeSavedInfo> CSI,103const TargetRegisterInfo *TRI) const override;104105bool hasFP(const MachineFunction &MF) const override;106bool hasReservedCallFrame(const MachineFunction &MF) const override;107bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;108bool needsFrameIndexResolution(const MachineFunction &MF) const override;109110StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,111Register &FrameReg) const override;112113int getWin64EHFrameIndexRef(const MachineFunction &MF, int FI,114Register &SPReg) const;115StackOffset getFrameIndexReferenceSP(const MachineFunction &MF, int FI,116Register &SPReg, int Adjustment) const;117StackOffset118getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,119Register &FrameReg,120bool IgnoreSPUpdates) const override;121122MachineBasicBlock::iterator123eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,124MachineBasicBlock::iterator MI) const override;125126unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;127128void processFunctionBeforeFrameFinalized(MachineFunction &MF,129RegScavenger *RS) const override;130131void132processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF,133RegScavenger *RS) const override;134135/// Check the instruction before/after the passed instruction. If136/// it is an ADD/SUB/LEA instruction it is deleted argument and the137/// stack adjustment is returned as a positive value for ADD/LEA and138/// a negative for SUB.139int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,140bool doMergeWithPrevious) const;141142/// Emit a series of instructions to increment / decrement the stack143/// pointer by a constant value.144void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,145const DebugLoc &DL, int64_t NumBytes, bool InEpilogue) const;146147/// Check that LEA can be used on SP in an epilogue sequence for \p MF.148bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const;149150/// Check whether or not the given \p MBB can be used as a prologue151/// for the target.152/// The prologue will be inserted first in this basic block.153/// This method is used by the shrink-wrapping pass to decide if154/// \p MBB will be correctly handled by the target.155/// As soon as the target enable shrink-wrapping without overriding156/// this method, we assume that each basic block is a valid157/// prologue.158bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;159160/// Check whether or not the given \p MBB can be used as a epilogue161/// for the target.162/// The epilogue will be inserted before the first terminator of that block.163/// This method is used by the shrink-wrapping pass to decide if164/// \p MBB will be correctly handled by the target.165bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;166167/// Returns true if the target will correctly handle shrink wrapping.168bool enableShrinkWrapping(const MachineFunction &MF) const override;169170/// Order the symbols in the local stack.171/// We want to place the local stack objects in some sort of sensible order.172/// The heuristic we use is to try and pack them according to static number173/// of uses and size in order to minimize code size.174void orderFrameObjects(const MachineFunction &MF,175SmallVectorImpl<int> &ObjectsToAllocate) const override;176177/// Wraps up getting a CFI index and building a MachineInstr for it.178void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,179const DebugLoc &DL, const MCCFIInstruction &CFIInst,180MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;181182/// Sets up EBP and optionally ESI based on the incoming EBP value. Only183/// needed for 32-bit. Used in funclet prologues and at catchret destinations.184MachineBasicBlock::iterator185restoreWin32EHStackPointers(MachineBasicBlock &MBB,186MachineBasicBlock::iterator MBBI,187const DebugLoc &DL, bool RestoreSP = false) const;188189void restoreWinEHStackPointersInParent(MachineFunction &MF) const;190191int getInitialCFAOffset(const MachineFunction &MF) const override;192193Register getInitialCFARegister(const MachineFunction &MF) const override;194195DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override;196197/// Return true if the function has a redzone (accessible bytes past the198/// frame of the top of stack function) as part of it's ABI.199bool has128ByteRedZone(const MachineFunction& MF) const;200201private:202bool isWin64Prologue(const MachineFunction &MF) const;203204bool needsDwarfCFI(const MachineFunction &MF) const;205206uint64_t calculateMaxStackAlign(const MachineFunction &MF) const;207208/// Emit target stack probe as a call to a helper function209void emitStackProbeCall(210MachineFunction &MF, MachineBasicBlock &MBB,211MachineBasicBlock::iterator MBBI, const DebugLoc &DL, bool InProlog,212std::optional<MachineFunction::DebugInstrOperandPair> InstrNum) const;213214/// Emit target stack probe as an inline sequence.215void emitStackProbeInline(MachineFunction &MF, MachineBasicBlock &MBB,216MachineBasicBlock::iterator MBBI,217const DebugLoc &DL, bool InProlog) const;218void emitStackProbeInlineWindowsCoreCLR64(MachineFunction &MF,219MachineBasicBlock &MBB,220MachineBasicBlock::iterator MBBI,221const DebugLoc &DL,222bool InProlog) const;223void emitStackProbeInlineGeneric(MachineFunction &MF, MachineBasicBlock &MBB,224MachineBasicBlock::iterator MBBI,225const DebugLoc &DL, bool InProlog) const;226227void emitStackProbeInlineGenericBlock(MachineFunction &MF,228MachineBasicBlock &MBB,229MachineBasicBlock::iterator MBBI,230const DebugLoc &DL, uint64_t Offset,231uint64_t Align) const;232233void emitStackProbeInlineGenericLoop(MachineFunction &MF,234MachineBasicBlock &MBB,235MachineBasicBlock::iterator MBBI,236const DebugLoc &DL, uint64_t Offset,237uint64_t Align) const;238239/// Emit target zero call-used regs.240void emitZeroCallUsedRegs(BitVector RegsToZero,241MachineBasicBlock &MBB) const override;242243void adjustFrameForMsvcCxxEh(MachineFunction &MF) const;244245/// Aligns the stack pointer by ANDing it with -MaxAlign.246void BuildStackAlignAND(MachineBasicBlock &MBB,247MachineBasicBlock::iterator MBBI, const DebugLoc &DL,248unsigned Reg, uint64_t MaxAlign) const;249250/// Make small positive stack adjustments using POPs.251bool adjustStackWithPops(MachineBasicBlock &MBB,252MachineBasicBlock::iterator MBBI, const DebugLoc &DL,253int Offset) const;254255/// Adjusts the stack pointer using LEA, SUB, or ADD.256MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB,257MachineBasicBlock::iterator MBBI,258const DebugLoc &DL, int64_t Offset,259bool InEpilogue) const;260261unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const;262263unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;264265/// Materialize the catchret target MBB in RAX.266void emitCatchRetReturnValue(MachineBasicBlock &MBB,267MachineBasicBlock::iterator MBBI,268MachineInstr *CatchRet) const;269};270271} // End llvm namespace272273#endif274275276