73#define DEBUG_TYPE "prologepilog"
77STATISTIC(NumLeafFuncWithSpills,
"Number of leaf functions with CSRs");
78STATISTIC(NumFuncSeen,
"Number of functions seen in PEI");
102 unsigned MinCSFrameIndex = std::numeric_limits<unsigned>::max();
103 unsigned MaxCSFrameIndex = 0;
113 bool FrameIndexVirtualScavenging =
false;
117 bool FrameIndexEliminationScavenging =
false;
134 unsigned OpIdx,
int SPAdj = 0);
165 "Number of bytes used for stack in all functions");
188 for (
auto &
MI :
MBB) {
189 if (!
MI.isDebugInstr())
191 if (!
MI.isDebugValue() || !
MI.getDebugVariable()->isParameter())
203 return Var == DV->getDebugVariable() &&
210 EntryDbgValues[&
MBB].push_back(&
MI);
215 for (
auto *
MI : EntryDbgValues[&
MBB])
216 MI->removeFromParent();
227 RS =
TRI->requiresRegisterScavenging(MF) ?
new RegScavenger() : nullptr;
228 FrameIndexVirtualScavenging =
TRI->requiresFrameIndexScavenging(MF);
229 ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
234 calculateCallFrameInfo(MF);
238 calculateSaveRestoreBlocks(MF);
247 spillCalleeSavedRegs(MF);
254 calculateFrameObjectOffsets(MF);
261 if (!
F.hasFnAttribute(Attribute::Naked))
262 insertPrologEpilogCode(MF);
265 for (
auto &
I : EntryDbgValues)
266 I.first->insert(
I.first->begin(),
I.second.begin(),
I.second.end());
276 FrameIndexEliminationScavenging =
277 (RS && !FrameIndexVirtualScavenging) ||
278 TRI->requiresFrameIndexReplacementScavenging(MF);
280 if (
TRI->eliminateFrameIndicesBackwards())
281 replaceFrameIndicesBackward(MF);
283 replaceFrameIndices(MF);
289 if (
TRI->requiresRegisterScavenging(MF) && FrameIndexVirtualScavenging)
303 assert(!
Failed &&
"Invalid warn-stack-size fn attr value");
308 StackSize += UnsafeStackSize;
310 if (StackSize > Threshold) {
312 F.getContext().diagnose(DiagStackSize);
313 int64_t SpillSize = 0;
320 [[maybe_unused]]
float SpillPct =
321 static_cast<float>(SpillSize) /
static_cast<float>(StackSize);
323 dbgs() <<
formatv(
"{0}/{1} ({3:P}) spills, {2}/{1} ({4:P}) variables",
324 SpillSize, StackSize, StackSize - SpillSize, SpillPct,
326 if (UnsafeStackSize != 0) {
329 static_cast<float>(UnsafeStackSize) /
330 static_cast<float>(StackSize),
340 <<
ore::NV(
"NumStackBytes", StackSize) <<
" stack bytes in function";
345 RestoreBlocks.clear();
359 unsigned MaxCallFrameSize = 0;
363 unsigned FrameSetupOpcode =
TII.getCallFrameSetupOpcode();
364 unsigned FrameDestroyOpcode =
TII.getCallFrameDestroyOpcode();
368 if (FrameSetupOpcode == ~0u && FrameDestroyOpcode == ~0u)
371 std::vector<MachineBasicBlock::iterator> FrameSDOps;
374 if (
TII.isFrameInstr(*
I)) {
375 unsigned Size =
TII.getFrameSize(*
I);
376 if (
Size > MaxCallFrameSize) MaxCallFrameSize =
Size;
378 FrameSDOps.push_back(
I);
379 }
else if (
I->isInlineAsm()) {
430 SaveBlocks.push_back(&MF.
front());
433 SaveBlocks.push_back(&
MBB);
435 RestoreBlocks.push_back(&
MBB);
441 unsigned &MinCSFrameIndex,
442 unsigned &MaxCSFrameIndex) {
443 if (SavedRegs.
empty())
447 const MCPhysReg *CSRegs =
F.getRegInfo().getCalleeSavedRegs();
450 for (
unsigned i = 0; CSRegs[i]; ++i)
451 CSMask.
set(CSRegs[i]);
453 std::vector<CalleeSavedInfo> CSI;
454 for (
unsigned i = 0; CSRegs[i]; ++i) {
455 unsigned Reg = CSRegs[i];
456 if (SavedRegs.
test(Reg)) {
457 bool SavedSuper =
false;
461 if (SavedRegs.
test(SuperReg) && CSMask.
test(SuperReg)) {
481 unsigned NumFixedSpillSlots;
487 for (
auto &CS : CSI) {
490 if (CS.isSpilledToReg())
493 unsigned Reg = CS.getReg();
497 if (
RegInfo->hasReservedSpillSlot(
F, Reg, FrameIdx)) {
498 CS.setFrameIdx(FrameIdx);
505 while (FixedSlot != FixedSpillSlots + NumFixedSpillSlots &&
506 FixedSlot->
Reg != Reg)
510 if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
518 if ((
unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
519 if ((
unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
525 CS.setFrameIdx(FrameIdx);
564 while (!WorkList.
empty()) {
568 if (CurBB == Save && Save != Restore)
573 if (Visited.
insert(SuccBB).second)
593 if (
I.isSpilledToReg()) {
595 if (Visited.count(&
MBB))
617 unsigned Reg = CS.getReg();
619 if (CS.isSpilledToReg()) {
621 TII.get(TargetOpcode::COPY), CS.getDstReg())
634 std::vector<CalleeSavedInfo> &CSI) {
646 unsigned Reg = CI.getReg();
647 if (CI.isSpilledToReg()) {
655 "loadRegFromStackSlot didn't insert any code!");
670 MachineFunctionProperties::Property::NoVRegs));
675 MinCSFrameIndex = std::numeric_limits<unsigned>::max();
686 if (!
F.hasFnAttribute(Attribute::Naked)) {
692 NumLeafFuncWithSpills++;
708 bool StackGrowsDown, int64_t &
Offset,
718 MaxAlign = std::max(MaxAlign, Alignment);
723 if (StackGrowsDown) {
739 unsigned MinCSFrameIndex,
unsigned MaxCSFrameIndex,
740 int64_t FixedCSEnd,
BitVector &StackBytesFree) {
742 if (FixedCSEnd > std::numeric_limits<int>::max())
745 StackBytesFree.
resize(FixedCSEnd,
true);
754 if (MinCSFrameIndex <= MaxCSFrameIndex) {
755 for (
int i = MinCSFrameIndex; i <= (int)MaxCSFrameIndex; ++i)
760 for (
int i : AllocatedFrameSlots) {
765 int ObjStart, ObjEnd;
766 if (StackGrowsDown) {
768 ObjStart = -ObjOffset - ObjSize;
771 ObjStart = ObjOffset;
772 ObjEnd = ObjOffset + ObjSize;
776 StackBytesFree.
reset(ObjStart, ObjEnd);
783 bool StackGrowsDown,
Align MaxAlign,
788 if (StackBytesFree.
none()) {
791 StackBytesFree.
clear();
796 if (ObjAlign > MaxAlign)
801 for (FreeStart = StackBytesFree.
find_first(); FreeStart != -1;
802 FreeStart = StackBytesFree.
find_next(FreeStart)) {
805 unsigned ObjStart = StackGrowsDown ? FreeStart + ObjSize : FreeStart;
806 if (
alignTo(ObjStart, ObjAlign) != ObjStart)
809 if (FreeStart + ObjSize > StackBytesFree.
size())
812 bool AllBytesFree =
true;
813 for (
unsigned Byte = 0; Byte < ObjSize; ++Byte)
814 if (!StackBytesFree.
test(FreeStart + Byte)) {
815 AllBytesFree =
false;
825 if (StackGrowsDown) {
826 int ObjStart = -(FreeStart + ObjSize);
827 LLVM_DEBUG(
dbgs() <<
"alloc FI(" << FrameIdx <<
") scavenged at SP["
828 << ObjStart <<
"]\n");
831 LLVM_DEBUG(
dbgs() <<
"alloc FI(" << FrameIdx <<
") scavenged at SP["
832 << FreeStart <<
"]\n");
836 StackBytesFree.
reset(FreeStart, FreeStart + ObjSize);
847 for (
int i : UnassignedObjs) {
858 bool StackGrowsDown =
869 LocalAreaOffset = -LocalAreaOffset;
870 assert(LocalAreaOffset >= 0
871 &&
"Local area offset should be in direction of stack growth");
872 int64_t
Offset = LocalAreaOffset;
874#ifdef EXPENSIVE_CHECKS
879 "MaxAlignment is invalid");
892 if (StackGrowsDown) {
908 if (MaxCSFrameIndex >= MinCSFrameIndex) {
909 for (
unsigned i = 0; i <= MaxCSFrameIndex - MinCSFrameIndex; ++i) {
911 StackGrowsDown ? MinCSFrameIndex + i : MaxCSFrameIndex - i;
926 "MFI.getMaxAlign should already account for all callee-saved "
927 "registers without a fixed stack slot");
931 int64_t FixedCSEnd =
Offset;
938 if (RS && EarlyScavengingSlots) {
940 RS->getScavengingFrameIndices(SFIs);
960 int64_t FIOffset = (StackGrowsDown ? -
Offset :
Offset) + Entry.second;
961 LLVM_DEBUG(
dbgs() <<
"alloc FI(" << Entry.first <<
") at SP[" << FIOffset
968 MaxAlign = std::max(Alignment, MaxAlign);
972 int EHRegNodeFrameIndex = std::numeric_limits<int>::max();
974 EHRegNodeFrameIndex = FuncInfo->EHRegNodeFrameIndex;
993 "Offset of stack protector on non-default stack expected to be "
996 "Stack protector on non-default stack expected to not be "
997 "pre-allocated by LocalStackSlotPass.");
1003 "Stack protector not pre-allocated by LocalStackSlotPass.");
1010 if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
1012 if (RS && RS->isScavengingFrameIndex((
int)i))
1016 if (StackProtectorFI == (
int)i || EHRegNodeFrameIndex == (
int)i)
1026 SmallArrayObjs.
insert(i);
1032 LargeArrayObjs.
insert(i);
1042 !(LargeArrayObjs.
empty() && SmallArrayObjs.
empty() &&
1043 AddrOfObjs.
empty()))
1045 "LocalStackSlotPass.");
1062 if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
1064 if (RS && RS->isScavengingFrameIndex((
int)i))
1070 if (ProtectedObjs.
count(i))
1081 if (EHRegNodeFrameIndex != std::numeric_limits<int>::max())
1095 if (!ObjectsToAllocate.
empty() &&
1099 FixedCSEnd, StackBytesFree);
1102 for (
auto &Object : ObjectsToAllocate)
1109 if (RS && !EarlyScavengingSlots) {
1111 RS->getScavengingFrameIndices(SFIs);
1112 for (
int SFI : SFIs)
1138 int64_t OffsetBeforeAlignment =
Offset;
1144 if (StackGrowsDown && OffsetBeforeAlignment !=
Offset && RS &&
1145 !EarlyScavengingSlots) {
1147 RS->getScavengingFrameIndices(SFIs);
1149 <<
"Adjusting emergency spill slots!\n";);
1150 int64_t Delta =
Offset - OffsetBeforeAlignment;
1151 for (
int SFI : SFIs) {
1153 <<
"Adjusting offset of emergency spill slot #" << SFI
1162 int64_t StackSize =
Offset - LocalAreaOffset;
1164 NumBytesStackSpace += StackSize;
1182 insertZeroCallUsedRegs(MF);
1210 if (!
F.hasFnAttribute(
"zero-call-used-regs"))
1213 using namespace ZeroCallUsedRegs;
1217 F.getFnAttribute(
"zero-call-used-regs").getValueAsString())
1218 .
Case(
"skip", ZeroCallUsedRegsKind::Skip)
1219 .
Case(
"used-gpr-arg", ZeroCallUsedRegsKind::UsedGPRArg)
1220 .
Case(
"used-gpr", ZeroCallUsedRegsKind::UsedGPR)
1221 .
Case(
"used-arg", ZeroCallUsedRegsKind::UsedArg)
1222 .
Case(
"used", ZeroCallUsedRegsKind::Used)
1223 .
Case(
"all-gpr-arg", ZeroCallUsedRegsKind::AllGPRArg)
1224 .
Case(
"all-gpr", ZeroCallUsedRegsKind::AllGPR)
1225 .
Case(
"all-arg", ZeroCallUsedRegsKind::AllArg)
1226 .
Case(
"all", ZeroCallUsedRegsKind::All);
1228 if (ZeroRegsKind == ZeroCallUsedRegsKind::Skip)
1231 const bool OnlyGPR =
static_cast<unsigned>(ZeroRegsKind) & ONLY_GPR;
1232 const bool OnlyUsed =
static_cast<unsigned>(ZeroRegsKind) & ONLY_USED;
1233 const bool OnlyArg =
static_cast<unsigned>(ZeroRegsKind) & ONLY_ARG;
1236 const BitVector AllocatableSet(
TRI.getAllocatableSet(MF));
1244 if (
MI.isDebugInstr())
1252 if (AllocatableSet[Reg] && !MO.isImplicit() &&
1253 (MO.isDef() || MO.isUse()))
1261 LiveIns.set(LI.PhysReg);
1264 for (
MCRegister Reg : AllocatableSet.set_bits()) {
1266 if (
TRI.isFixedRegister(MF, Reg))
1270 if (OnlyGPR && !
TRI.isGeneralPurposeRegister(MF, Reg))
1274 if (OnlyUsed && !UsedRegs[Reg])
1282 }
else if (!
TRI.isArgumentRegister(MF, Reg)) {
1287 RegsToZero.set(Reg);
1296 for (
const auto &MO :
MI.operands()) {
1306 RegsToZero.reset(Unit);
1308 for (
MCPhysReg SReg :
TRI.sub_and_superregs_inclusive(Reg))
1309 RegsToZero.reset(SReg);
1330 for (
const MCPhysReg Reg :
TRI.sub_and_superregs_inclusive(Reg))
1331 RegsToZero.reset(Reg);
1337 for (
const MCPhysReg *CSRegs =
TRI.getCalleeSavedRegs(&MF);
1339 for (
MCRegister Reg :
TRI.sub_and_superregs_inclusive(CSReg))
1340 RegsToZero.reset(Reg);
1353 for (
auto &
MBB : MF) {
1359 return Succ->getCallFrameSize() ==
1360 (*MBB.succ_begin())->getCallFrameSize();
1368 replaceFrameIndicesBackward(&
MBB, MF, SPAdj);
1381 for (
auto &
MBB : MF) {
1386 replaceFrameIndices(&
MBB, MF, SPAdj);
1395 unsigned OpIdx,
int SPAdj) {
1398 if (
MI.isDebugValue()) {
1402 "Frame indices can only appear as a debug operand in a DBG_VALUE*"
1403 " machine instruction");
1405 unsigned FrameIdx =
Op.getIndex();
1409 Op.ChangeToRegister(Reg,
false );
1419 if (
MI.isNonListDebugValue()) {
1421 if (!
MI.isIndirectDebugValue() && !DIExpr->
isComplex())
1428 if (
MI.isIndirectDebugValue() && DIExpr->
isImplicit()) {
1430 bool WithStackValue =
true;
1433 MI.getDebugOffset().ChangeToRegister(0,
false);
1435 DIExpr =
TRI.prependOffsetExpression(DIExpr, PrependFlags,
Offset);
1440 unsigned DebugOpIndex =
MI.getDebugOperandIndex(&
Op);
1445 MI.getDebugExpressionOp().setMetadata(DIExpr);
1449 if (
MI.isDebugPHI()) {
1459 if (
MI.getOpcode() == TargetOpcode::STATEPOINT) {
1460 assert((!
MI.isDebugValue() || OpIdx == 0) &&
1461 "Frame indicies can only appear as the first operand of a "
1462 "DBG_VALUE machine instruction");
1466 MF,
MI.getOperand(OpIdx).getIndex(), Reg,
false);
1468 "Frame offsets with a scalable component are not supported");
1470 MI.getOperand(OpIdx).ChangeToRegister(Reg,
false );
1479 "getRegisterInfo() must be implemented!");
1485 RegScavenger *LocalRS = FrameIndexEliminationScavenging ? RS :
nullptr;
1492 if (
TII.isFrameInstr(
MI)) {
1493 SPAdj -=
TII.getSPAdjust(
MI);
1502 bool RemovedMI =
false;
1507 if (replaceFrameIndexDebugInstr(MF,
MI,
Idx, SPAdj))
1511 RemovedMI =
TRI.eliminateFrameIndex(
MI, SPAdj,
Idx, LocalRS);
1519 LocalRS->
skipTo(std::prev(
I));
1529 "getRegisterInfo() must be implemented!");
1534 bool InsideCallSequence =
false;
1537 if (
TII.isFrameInstr(*
I)) {
1538 InsideCallSequence =
TII.isFrameSetup(*
I);
1539 SPAdj +=
TII.getSPAdjust(*
I);
1546 bool DidFinishLoop =
true;
1547 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
1548 if (!
MI.getOperand(i).isFI())
1551 if (replaceFrameIndexDebugInstr(MF,
MI, i, SPAdj))
1561 bool AtBeginning = (
I == BB->
begin());
1562 if (!AtBeginning) --
I;
1567 TRI.eliminateFrameIndex(
MI, SPAdj, i);
1575 DidFinishLoop =
false;
1586 if (DidFinishLoop && InsideCallSequence)
1587 SPAdj +=
TII.getSPAdjust(
MI);
1589 if (DoIncr &&
I != BB->
end())
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static void insertCSRRestores(MachineBasicBlock &RestoreBlock, std::vector< CalleeSavedInfo > &CSI)
Insert restore code for the callee-saved registers used in the function.
static bool scavengeStackSlot(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, Align MaxAlign, BitVector &StackBytesFree)
Assign frame object to an unused portion of the stack in the fixed stack object range.
static void insertCSRSaves(MachineBasicBlock &SaveBlock, ArrayRef< CalleeSavedInfo > CSI)
Insert spill code for the callee-saved registers used in the function.
static void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, SmallSet< int, 16 > &ProtectedObjs, MachineFrameInfo &MFI, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign)
AssignProtectedObjSet - Helper function to assign large stack objects (i.e., those required to be clo...
static void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
static void updateLiveness(MachineFunction &MF)
Helper function to update the liveness information for the callee-saved registers.
static void assignCalleeSavedSpillSlots(MachineFunction &F, const BitVector &SavedRegs, unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex)
Prologue Epilogue Insertion &Frame Finalization
static void stashEntryDbgValues(MachineBasicBlock &MBB, SavedDbgValuesMap &EntryDbgValues)
Stash DBG_VALUEs that describe parameters and which are placed at the start of the block.
static void computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown, unsigned MinCSFrameIndex, unsigned MaxCSFrameIndex, int64_t FixedCSEnd, BitVector &StackBytesFree)
Compute which bytes of fixed and callee-save stack area are unused and keep track of them in StackByt...
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
StringRef getValueAsString() const
Return the attribute's value as a string.
bool test(unsigned Idx) const
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
void clear()
clear - Removes all bits from the bitvector.
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
bool none() const
none - Returns true if none of the bits are set.
size_type size() const
size - Returns the number of bits in this bitvector.
bool empty() const
empty - Tests whether there are no bits in this bitvector.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
bool isImplicit() const
Return whether this is an implicit location description.
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)
Check if fragments overlap between a pair of FragmentInfos.
static DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
static DIExpression * prependOpcodes(const DIExpression *Expr, SmallVectorImpl< uint64_t > &Ops, bool StackValue=false, bool EntryValue=false)
Prepend DIExpr with the given opcodes and optionally turn it into a stack value.
This class represents an Operation in the Expression.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
DISubprogram * getSubprogram() const
Get the attached subprogram.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Store the specified register of the given register class to the specified stack frame index.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Load the specified register of the given register class from the specified stack frame index.
virtual bool usesPhysRegsForValues() const
True if the target uses physical regs (as nearly all targets do).
Wrapper class representing physical registers. Should be passed by value.
void push_back(MachineInstr *MI)
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
succ_iterator succ_begin()
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< iterator > terminators()
unsigned getCallFrameSize() const
Return the call frame size on entry to this basic block.
iterator_range< succ_iterator > successors()
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
void setAdjustsStack(bool V)
void setRestorePoint(MachineBasicBlock *NewRestore)
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
int64_t getLocalFrameObjectCount() const
Return the number of objects allocated into the local object block.
bool hasCalls() const
Return true if the current function has any function calls.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Align getLocalFrameMaxAlign() const
Return the required alignment of the local object blob.
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
@ SSPLK_SmallArray
Array or nested array < SSP-buffer-size.
@ SSPLK_LargeArray
Array or nested array >= SSP-buffer-size.
@ SSPLK_AddrOf
The address of this allocation is exposed and triggered protection.
@ SSPLK_None
Did not trigger a stack protector.
std::pair< int, int64_t > getLocalFrameObjectMap(int i) const
Get the local offset mapping for a for an object.
bool getUseLocalStackAllocationBlock() const
Get whether the local allocation blob should be allocated together or let PEI allocate the locals in ...
MachineBasicBlock * getRestorePoint() const
int getStackProtectorIndex() const
Return the index for the stack protector object.
void setCalleeSavedInfoValid(bool v)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool isMaxCallFrameSizeComputed() const
int64_t getLocalFrameSize() const
Get the size of the local object blob.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
void setCalleeSavedInfo(std::vector< CalleeSavedInfo > CSI)
Used by prolog/epilog inserter to set the function's callee saved information.
bool isVariableSizedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a variable sized object.
void setSavePoint(MachineBasicBlock *NewSave)
uint64_t getUnsafeStackSize() const
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasStackProtectorIndex() const
void setMaxCallFrameSize(unsigned S)
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
uint8_t getStackID(int ObjectIdx) const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
MachineBasicBlock * getSavePoint() const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool hasProperty(Property P) const
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool shouldSplitStack() const
Should we be emitting segmented stack stuff for the function.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineBasicBlock & front() const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void backward()
Update internal register state and move MBB iterator backwards.
void skipTo(MachineBasicBlock::iterator I)
Move the internal MBB iterator but do not update register states.
Wrapper class representing virtual and physical registers.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
static StackOffset getScalable(int64_t Scalable)
static StackOffset getFixed(int64_t Fixed)
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Information about stack frame layout on the target.
virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
virtual const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
virtual bool enableStackSlotScavenging(const MachineFunction &MF) const
Returns true if the stack slot holes in the fixed and callee-save stack area should be used when allo...
virtual bool allocateScavengingFrameIndexesNearIncomingSP(const MachineFunction &MF) const
Control the placement of special register scavenging spill slots when allocating a stack frame.
Align getTransientStackAlign() const
getTransientStackAlignment - This method returns the number of bytes to which the stack pointer must ...
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
virtual uint64_t getStackThreshold() const
getStackThreshold - Return the maximum stack size
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
virtual void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const
Replace a StackProbe stub (if any) with the actual probe code inline.
virtual void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &objectsToAllocate) const
Order the symbols in the local stack frame.
virtual void adjustForHiPEPrologue(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const
Adjust the prologue to add Erlang Run-Time System (ERTS) specific code in the assembly prologue to ex...
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
virtual bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI, unsigned &MinCSFrameIndex, unsigned &MaxCSFrameIndex) const
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
virtual bool needsFrameIndexResolution(const MachineFunction &MF) const
virtual MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
virtual void processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF, RegScavenger *RS=nullptr) const
processFunctionBeforeFrameIndicesReplaced - This method is called immediately before MO_FrameIndex op...
virtual StackOffset getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI, Register &FrameReg, bool IgnoreSPUpdates) const
Same as getFrameIndexReference, except that the stack pointer (as opposed to the frame pointer) will ...
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
virtual void adjustForSegmentedStacks(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const
Adjust the prologue to have the function use segmented stacks.
int alignSPAdjust(int SPAdj) const
alignSPAdjust - This method aligns the stack adjustment to the correct alignment.
virtual bool canSimplifyCallFramePseudos(const MachineFunction &MF) const
canSimplifyCallFramePseudos - When possible, it's best to simplify the call frame pseudo ops before d...
virtual void emitZeroCallUsedRegs(BitVector RegsToZero, MachineBasicBlock &MBB) const
emitZeroCallUsedRegs - Zeros out call used registers.
virtual bool targetHandlesStackFrameRounding() const
targetHandlesStackFrameRounding - Returns true if the target is responsible for rounding up the stack...
virtual void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const =0
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
TargetInstrInfo - Interface to description of machine instruction set.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
unsigned StackSymbolOrdering
StackSymbolOrdering - When true, this will allow CodeGen to order the local stack symbols (for code s...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ HiPE
Used by the High-Performance Erlang Compiler (HiPE).
Reg
All possible values of the reg field in the ModR/M byte.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
testing::Matcher< const detail::ErrorHolder & > Failed()
void scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS)
Replaces all frame index virtual registers with physical registers.
MachineFunctionPass * createPrologEpilogInserterPass()
char & PrologEpilogCodeInserterID
PrologEpilogCodeInserter - This pass inserts prolog and epilog code, and eliminates abstract frame re...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
unsigned getKillRegState(bool B)
void initializePEIPass(PassRegistry &)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Pair of physical register and lane mask.