71#define DEBUG_TYPE "prolog-epilog"
75STATISTIC(NumLeafFuncWithSpills,
"Number of leaf functions with CSRs");
76STATISTIC(NumFuncSeen,
"Number of functions seen in PEI");
92 bool FrameIndexVirtualScavenging =
false;
96 bool FrameIndexEliminationScavenging =
false;
113 unsigned OpIdx,
int SPAdj = 0);
125 bool run(MachineFunction &MF);
132 PEILegacy() : MachineFunctionPass(ID) {}
134 void getAnalysisUsage(AnalysisUsage &AU)
const override;
138 bool runOnMachineFunction(MachineFunction &MF)
override;
143char PEILegacy::ID = 0;
153 "Prologue/Epilogue Insertion & Frame Finalization",
false,
157 return new PEILegacy();
161 "Number of bytes used for stack in all functions");
185 for (
auto &
MI :
MBB) {
186 if (!
MI.isDebugInstr())
188 if (!
MI.isDebugValue() || !
MI.getDebugVariable()->isParameter())
200 return Var == DV->getDebugVariable() &&
207 EntryDbgValues[&
MBB].push_back(&
MI);
211 if (
auto It = EntryDbgValues.find(&
MBB); It != EntryDbgValues.end())
212 for (
auto *
MI : It->second)
213 MI->removeFromParent();
216bool PEIImpl::run(MachineFunction &MF) {
222 RS =
TRI->requiresRegisterScavenging(MF) ?
new RegScavenger() : nullptr;
223 FrameIndexVirtualScavenging =
TRI->requiresFrameIndexScavenging(MF);
232 calculateCallFrameInfo(MF);
236 calculateSaveRestoreBlocks(MF);
240 for (MachineBasicBlock *SaveBlock : SaveBlocks)
245 spillCalleeSavedRegs(MF);
252 calculateFrameObjectOffsets(MF);
259 if (!
F.hasFnAttribute(Attribute::Naked))
260 insertPrologEpilogCode(MF);
263 for (
auto &
I : EntryDbgValues)
264 I.first->insert(
I.first->begin(),
I.second.begin(),
I.second.end());
274 FrameIndexEliminationScavenging =
275 (RS && !FrameIndexVirtualScavenging) ||
276 TRI->requiresFrameIndexReplacementScavenging(MF);
278 if (
TRI->eliminateFrameIndicesBackwards())
279 replaceFrameIndicesBackward(MF);
281 replaceFrameIndices(MF);
287 if (
TRI->requiresRegisterScavenging(MF) && FrameIndexVirtualScavenging)
301 assert(!
Failed &&
"Invalid warn-stack-size fn attr value");
306 StackSize += UnsafeStackSize;
308 if (StackSize > Threshold) {
309 DiagnosticInfoStackSize DiagStackSize(
F, StackSize, Threshold,
DS_Warning);
310 F.getContext().diagnose(DiagStackSize);
311 int64_t SpillSize = 0;
318 [[maybe_unused]]
float SpillPct =
319 static_cast<float>(SpillSize) /
static_cast<float>(StackSize);
321 dbgs() <<
formatv(
"{0}/{1} ({3:P}) spills, {2}/{1} ({4:P}) variables",
322 SpillSize, StackSize, StackSize - SpillSize, SpillPct,
324 if (UnsafeStackSize != 0) {
327 static_cast<float>(UnsafeStackSize) /
328 static_cast<float>(StackSize),
335 return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE,
"StackSize",
338 <<
ore::NV(
"NumStackBytes", StackSize)
339 <<
" stack bytes in function '"
348 RestoreBlocks.
clear();
356bool PEILegacy::runOnMachineFunction(MachineFunction &MF) {
357 MachineOptimizationRemarkEmitter *ORE =
358 &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
359 return PEIImpl(ORE).run(MF);
367 if (!PEIImpl(&ORE).
run(MF))
372 .preserve<MachineDominatorTreeAnalysis>()
384 unsigned FrameSetupOpcode =
TII.getCallFrameSetupOpcode();
385 unsigned FrameDestroyOpcode =
TII.getCallFrameDestroyOpcode();
389 if (FrameSetupOpcode == ~0u && FrameDestroyOpcode == ~0u)
393 [[maybe_unused]]
uint64_t MaxCFSIn =
395 std::vector<MachineBasicBlock::iterator> FrameSDOps;
398 "Recomputing MaxCFS gave a larger value.");
400 "AdjustsStack not set in presence of a frame pseudo instruction.");
413 MBB.setCallFrameSize(0);
419void PEIImpl::calculateSaveRestoreBlocks(MachineFunction &MF) {
428 "Multiple save points are not yet supported!");
430 SaveBlocks.push_back(SavePoint.first);
432 "Multiple restore points are not yet supported!");
434 MachineBasicBlock *RestoreBlock = RestorePoint.first;
444 SaveBlocks.push_back(&MF.
front());
445 for (MachineBasicBlock &
MBB : MF) {
447 SaveBlocks.push_back(&
MBB);
455 if (SavedRegs.
empty())
459 const MCPhysReg *CSRegs =
F.getRegInfo().getCalleeSavedRegs();
462 for (
unsigned i = 0; CSRegs[i]; ++i)
463 CSMask.
set(CSRegs[i]);
465 std::vector<CalleeSavedInfo> CSI;
466 for (
unsigned i = 0; CSRegs[i]; ++i) {
467 unsigned Reg = CSRegs[i];
469 bool SavedSuper =
false;
473 if (SavedRegs.
test(SuperReg) && CSMask.
test(SuperReg)) {
492 unsigned NumFixedSpillSlots;
498 for (
auto &
CS : CSI) {
501 if (
CS.isSpilledToReg())
508 if (
RegInfo->hasReservedSpillSlot(
F,
Reg, FrameIdx)) {
509 CS.setFrameIdx(FrameIdx);
516 while (FixedSlot != FixedSpillSlots + NumFixedSpillSlots &&
521 if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
529 RegInfo->getSpillStackID(*RC));
536 CS.setFrameIdx(FrameIdx);
559 "Multiple save points not yet supported!");
574 "Multiple restore points not yet supported!");
584 while (!WorkList.
empty()) {
588 if (CurBB == Save && Save != Restore)
593 if (Visited.
insert(SuccBB).second)
613 if (
I.isSpilledToReg()) {
615 if (Visited.count(&
MBB))
618 if (!
MBB.isLiveIn(DstReg))
619 MBB.addLiveIn(DstReg);
643 std::vector<CalleeSavedInfo> &CSI) {
660void PEIImpl::spillCalleeSavedRegs(MachineFunction &MF) {
680 if (!
F.hasFnAttribute(Attribute::Naked)) {
689 SaveRestorePts.insert({SavePoint.first, CSI});
692 SaveRestorePts.clear();
694 SaveRestorePts.insert({RestorePoint.first, CSI});
700 NumLeafFuncWithSpills++;
702 for (MachineBasicBlock *SaveBlock : SaveBlocks)
708 for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
716 bool StackGrowsDown, int64_t &
Offset,
726 MaxAlign = std::max(MaxAlign, Alignment);
731 if (StackGrowsDown) {
750 if (FixedCSEnd > std::numeric_limits<int>::max())
753 StackBytesFree.
resize(FixedCSEnd,
true);
767 for (
int i : AllocatedFrameSlots) {
772 int ObjStart, ObjEnd;
773 if (StackGrowsDown) {
775 ObjStart = -ObjOffset - ObjSize;
778 ObjStart = ObjOffset;
779 ObjEnd = ObjOffset + ObjSize;
783 StackBytesFree.
reset(ObjStart, ObjEnd);
790 bool StackGrowsDown,
Align MaxAlign,
795 if (StackBytesFree.
none()) {
798 StackBytesFree.
clear();
803 if (ObjAlign > MaxAlign)
808 for (FreeStart = StackBytesFree.
find_first(); FreeStart != -1;
809 FreeStart = StackBytesFree.
find_next(FreeStart)) {
812 unsigned ObjStart = StackGrowsDown ? FreeStart + ObjSize : FreeStart;
813 if (
alignTo(ObjStart, ObjAlign) != ObjStart)
816 if (FreeStart + ObjSize > StackBytesFree.
size())
819 bool AllBytesFree =
true;
820 for (
unsigned Byte = 0; Byte < ObjSize; ++Byte)
821 if (!StackBytesFree.
test(FreeStart + Byte)) {
822 AllBytesFree =
false;
832 if (StackGrowsDown) {
833 int ObjStart = -(FreeStart + ObjSize);
834 LLVM_DEBUG(
dbgs() <<
"alloc FI(" << FrameIdx <<
") scavenged at SP["
835 << ObjStart <<
"]\n");
838 LLVM_DEBUG(
dbgs() <<
"alloc FI(" << FrameIdx <<
") scavenged at SP["
839 << FreeStart <<
"]\n");
843 StackBytesFree.
reset(FreeStart, FreeStart + ObjSize);
854 for (
int i : UnassignedObjs) {
862void PEIImpl::calculateFrameObjectOffsets(MachineFunction &MF) {
865 bool StackGrowsDown =
876 LocalAreaOffset = -LocalAreaOffset;
877 assert(LocalAreaOffset >= 0
878 &&
"Local area offset should be in direction of stack growth");
879 int64_t
Offset = LocalAreaOffset;
881#ifdef EXPENSIVE_CHECKS
886 "MaxAlignment is invalid");
899 if (StackGrowsDown) {
930 "MFI.getMaxAlign should already account for all callee-saved "
931 "registers without a fixed stack slot");
935 int64_t FixedCSEnd =
Offset;
942 if (RS && EarlyScavengingSlots) {
943 SmallVector<int, 2> SFIs;
972 MaxAlign = std::max(Alignment, MaxAlign);
976 int EHRegNodeFrameIndex = std::numeric_limits<int>::max();
978 EHRegNodeFrameIndex = FuncInfo->EHRegNodeFrameIndex;
982 SmallSet<int, 16> ProtectedObjs;
997 "Offset of stack protector on non-default stack expected to be "
1000 "Stack protector on non-default stack expected to not be "
1001 "pre-allocated by LocalStackSlotPass.");
1007 "Stack protector not pre-allocated by LocalStackSlotPass.");
1020 if (StackProtectorFI == (
int)i || EHRegNodeFrameIndex == (
int)i)
1030 SmallArrayObjs.
insert(i);
1036 LargeArrayObjs.
insert(i);
1046 !(LargeArrayObjs.
empty() && SmallArrayObjs.
empty() &&
1047 AddrOfObjs.
empty()))
1049 "LocalStackSlotPass.");
1059 SmallVector<int, 8> ObjectsToAllocate;
1074 if (ProtectedObjs.
count(i))
1085 if (EHRegNodeFrameIndex != std::numeric_limits<int>::max())
1098 BitVector StackBytesFree;
1099 if (!ObjectsToAllocate.
empty() &&
1105 for (
auto &Object : ObjectsToAllocate)
1112 if (RS && !EarlyScavengingSlots) {
1113 SmallVector<int, 2> SFIs;
1115 for (
int SFI : SFIs)
1140 StackAlign = std::max(StackAlign, MaxAlign);
1141 int64_t OffsetBeforeAlignment =
Offset;
1147 if (StackGrowsDown && OffsetBeforeAlignment !=
Offset && RS &&
1148 !EarlyScavengingSlots) {
1149 SmallVector<int, 2> SFIs;
1152 <<
"Adjusting emergency spill slots!\n";);
1153 int64_t Delta =
Offset - OffsetBeforeAlignment;
1154 for (
int SFI : SFIs) {
1156 <<
"Adjusting offset of emergency spill slot #" << SFI
1165 int64_t StackSize =
Offset - LocalAreaOffset;
1167 NumBytesStackSpace += StackSize;
1173void PEIImpl::insertPrologEpilogCode(MachineFunction &MF) {
1177 for (MachineBasicBlock *SaveBlock : SaveBlocks)
1181 for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
1185 insertZeroCallUsedRegs(MF);
1187 for (MachineBasicBlock *SaveBlock : SaveBlocks)
1195 for (MachineBasicBlock *SaveBlock : SaveBlocks)
1205 for (MachineBasicBlock *SaveBlock : SaveBlocks)
1210void PEIImpl::insertZeroCallUsedRegs(MachineFunction &MF) {
1213 if (!
F.hasFnAttribute(
"zero-call-used-regs"))
1216 using namespace ZeroCallUsedRegs;
1219 StringSwitch<ZeroCallUsedRegsKind>(
1220 F.getFnAttribute(
"zero-call-used-regs").getValueAsString())
1221 .Case(
"skip", ZeroCallUsedRegsKind::Skip)
1222 .Case(
"used-gpr-arg", ZeroCallUsedRegsKind::UsedGPRArg)
1223 .Case(
"used-gpr", ZeroCallUsedRegsKind::UsedGPR)
1224 .Case(
"used-arg", ZeroCallUsedRegsKind::UsedArg)
1225 .Case(
"used", ZeroCallUsedRegsKind::Used)
1226 .Case(
"all-gpr-arg", ZeroCallUsedRegsKind::AllGPRArg)
1227 .Case(
"all-gpr", ZeroCallUsedRegsKind::AllGPR)
1228 .Case(
"all-arg", ZeroCallUsedRegsKind::AllArg)
1229 .Case(
"all", ZeroCallUsedRegsKind::All);
1231 if (ZeroRegsKind == ZeroCallUsedRegsKind::Skip)
1234 const bool OnlyGPR =
static_cast<unsigned>(ZeroRegsKind) & ONLY_GPR;
1235 const bool OnlyUsed =
static_cast<unsigned>(ZeroRegsKind) & ONLY_USED;
1236 const bool OnlyArg =
static_cast<unsigned>(ZeroRegsKind) & ONLY_ARG;
1239 const BitVector AllocatableSet(
TRI.getAllocatableSet(MF));
1242 BitVector UsedRegs(
TRI.getNumRegs());
1244 for (
const MachineBasicBlock &
MBB : MF)
1245 for (
const MachineInstr &
MI :
MBB) {
1247 if (
MI.isDebugInstr())
1250 for (
const MachineOperand &MO :
MI.operands()) {
1254 MCRegister
Reg = MO.getReg();
1255 if (AllocatableSet[
Reg.
id()] && !MO.isImplicit() &&
1256 (MO.isDef() || MO.isUse()))
1257 UsedRegs.set(
Reg.
id());
1262 BitVector LiveIns(
TRI.getNumRegs());
1263 for (
const MachineBasicBlock::RegisterMaskPair &LI : MF.front().liveins())
1264 LiveIns.set(LI.PhysReg);
1266 BitVector RegsToZero(
TRI.getNumRegs());
1267 for (MCRegister
Reg : AllocatableSet.set_bits()) {
1269 if (
TRI.isFixedRegister(MF,
Reg))
1273 if (OnlyGPR && !
TRI.isGeneralPurposeRegister(MF,
Reg))
1277 if (OnlyUsed && !UsedRegs[
Reg.
id()])
1283 for (MCRegister LiveReg : LiveIns.set_bits()) {
1284 if (
TRI.regsOverlap(
Reg, LiveReg))
1285 RegsToZero.set(LiveReg);
1288 }
else if (!
TRI.isArgumentRegister(MF,
Reg)) {
1293 RegsToZero.set(
Reg.
id());
1297 for (
const MachineBasicBlock &
MBB : MF)
1302 for (
const auto &MO :
MI.operands()) {
1306 MCRegister
Reg = MO.getReg();
1312 for (MCRegUnit Unit :
TRI.regunits(
Reg))
1313 RegsToZero.reset(
static_cast<unsigned>(Unit));
1316 RegsToZero.reset(SReg);
1322 for (
const MachineBasicBlock &
MBB : MF) {
1329 for (
const MachineOperand &MO :
I->operands()) {
1333 MCRegister
Reg = MO.getReg();
1338 RegsToZero.reset(
Reg);
1344 for (
const MCPhysReg *CSRegs =
TRI.getCalleeSavedRegs(&MF);
1346 for (MCRegister
Reg :
TRI.sub_and_superregs_inclusive(CSReg))
1347 RegsToZero.reset(
Reg.
id());
1349 const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
1350 for (MachineBasicBlock &
MBB : MF)
1357void PEIImpl::replaceFrameIndicesBackward(MachineFunction &MF) {
1360 for (
auto &
MBB : MF) {
1366 return Succ->getCallFrameSize() ==
1367 (*MBB.succ_begin())->getCallFrameSize();
1375 replaceFrameIndicesBackward(&
MBB, MF, SPAdj);
1385void PEIImpl::replaceFrameIndices(MachineFunction &MF) {
1388 for (
auto &
MBB : MF) {
1393 replaceFrameIndices(&
MBB, MF, SPAdj);
1401bool PEIImpl::replaceFrameIndexDebugInstr(MachineFunction &MF, MachineInstr &
MI,
1402 unsigned OpIdx,
int SPAdj) {
1405 if (
MI.isDebugValue()) {
1407 MachineOperand &
Op =
MI.getOperand(
OpIdx);
1409 "Frame indices can only appear as a debug operand in a DBG_VALUE*"
1410 " machine instruction");
1412 unsigned FrameIdx =
Op.getIndex();
1416 Op.ChangeToRegister(
Reg,
false );
1418 const DIExpression *DIExpr =
MI.getDebugExpression();
1426 if (
MI.isNonListDebugValue()) {
1428 if (!
MI.isIndirectDebugValue() && !DIExpr->
isComplex())
1435 if (
MI.isIndirectDebugValue() && DIExpr->
isImplicit()) {
1437 bool WithStackValue =
true;
1440 MI.getDebugOffset().ChangeToRegister(0,
false);
1442 DIExpr =
TRI.prependOffsetExpression(DIExpr, PrependFlags,
Offset);
1447 unsigned DebugOpIndex =
MI.getDebugOperandIndex(&
Op);
1452 MI.getDebugExpressionOp().setMetadata(DIExpr);
1456 if (
MI.isDebugPHI()) {
1466 if (
MI.getOpcode() == TargetOpcode::STATEPOINT) {
1468 "Frame indices can only appear as the first operand of a "
1469 "DBG_VALUE machine instruction");
1473 MF,
MI.getOperand(
OpIdx).getIndex(),
Reg,
false);
1475 "Frame offsets with a scalable component are not supported");
1477 MI.getOperand(
OpIdx).ChangeToRegister(
Reg,
false );
1483void PEIImpl::replaceFrameIndicesBackward(MachineBasicBlock *BB,
1484 MachineFunction &MF,
int &SPAdj) {
1486 "getRegisterInfo() must be implemented!");
1492 RegScavenger *LocalRS = FrameIndexEliminationScavenging ? RS :
nullptr;
1497 MachineInstr &
MI = *std::prev(
I);
1499 if (
TII.isFrameInstr(
MI)) {
1500 SPAdj -=
TII.getSPAdjust(
MI);
1509 bool RemovedMI =
false;
1514 if (replaceFrameIndexDebugInstr(MF,
MI, Idx, SPAdj))
1518 RemovedMI =
TRI.eliminateFrameIndex(
MI, SPAdj, Idx, LocalRS);
1528void PEIImpl::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
1531 "getRegisterInfo() must be implemented!");
1536 bool InsideCallSequence =
false;
1539 if (
TII.isFrameInstr(*
I)) {
1540 InsideCallSequence =
TII.isFrameSetup(*
I);
1541 SPAdj +=
TII.getSPAdjust(*
I);
1546 MachineInstr &
MI = *
I;
1548 bool DidFinishLoop =
true;
1549 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
1550 if (!
MI.getOperand(i).isFI())
1553 if (replaceFrameIndexDebugInstr(MF,
MI, i, SPAdj))
1563 bool AtBeginning = (
I == BB->
begin());
1564 if (!AtBeginning) --
I;
1569 TRI.eliminateFrameIndex(
MI, SPAdj, i, RS);
1577 DidFinishLoop =
false;
1588 if (DidFinishLoop && InsideCallSequence)
1589 SPAdj +=
TII.getSPAdjust(
MI);
1591 if (DoIncr &&
I != BB->
end())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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")
const HexagonInstrInfo * TII
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
#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.
SmallVector< MachineBasicBlock *, 4 > MBBVector
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.
SmallDenseMap< MachineBasicBlock *, SmallVector< MachineInstr *, 4 >, 4 > SavedDbgValuesMap
static void computeFreeStackSlots(MachineFrameInfo &MFI, bool StackGrowsDown, int64_t FixedCSEnd, BitVector &StackBytesFree)
Compute which bytes of fixed and callee-save stack area are unused and keep track of them in StackByt...
static void updateLiveness(MachineFunction &MF)
Helper function to update the liveness information for the callee-saved registers.
SmallSetVector< int, 8 > StackObjSet
StackObjSet - A set of stack object indexes.
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 assignCalleeSavedSpillSlots(MachineFunction &F, const BitVector &SavedRegs)
This file declares the machine register scavenger class.
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)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
BitVector & reset()
Reset all bits in the bitvector.
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
void clear()
Removes all bits from the bitvector.
BitVector & set()
Set all bits in the bitvector.
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
bool none() const
Returns true if none of the bits are set.
size_type size() const
Returns the number of bits in this bitvector.
bool empty() const
Returns whether there are no bits in this bitvector.
Represents analyses that only rely on functions' control flow.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
LLVM_ABI 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 LLVM_ABI 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...
LLVM_ABI bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
static LLVM_ABI 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.
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.
Wrapper class representing physical registers. Should be passed by value.
MachineInstrBundleIterator< const MachineInstr > const_iterator
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
succ_iterator succ_begin()
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
LLVM_ABI 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.
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()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
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.
LLVM_ABI void computeMaxCallFrameSize(MachineFunction &MF, std::vector< MachineBasicBlock::iterator > *FrameSDOps=nullptr)
Computes the maximum size of a callframe.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
LLVM_ABI 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.
bool isCalleeSavedObjectIndex(int ObjectIdx) const
void clearRestorePoints()
std::pair< int, int64_t > getLocalFrameObjectMap(int i) const
Get the local offset mapping for a for an object.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setSavePoints(SaveRestorePoints NewSavePoints)
bool getUseLocalStackAllocationBlock() const
Get whether the local allocation blob should be allocated together or let PEI allocate the locals in ...
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.
uint64_t getUnsafeStackSize() const
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasStackProtectorIndex() const
void setRestorePoints(SaveRestorePoints NewRestorePoints)
LLVM_ABI 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
const SaveRestorePoints & getRestorePoints() const
void setIsCalleeSavedObjectIndex(int ObjectIdx, bool IsCalleeSaved)
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.
const SaveRestorePoints & getSavePoints() const
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
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.
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.
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 TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
LLVM_ABI void backward()
Update internal register state and move MBB iterator backwards.
void getScavengingFrameIndices(SmallVectorImpl< int > &A) const
Get an array of scavenging frame indices.
bool isScavengingFrameIndex(int FI) const
Query whether a frame index is a scavenging frame index.
constexpr unsigned id() const
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.
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.
Information about stack frame layout on the target.
virtual void spillFPBP(MachineFunction &MF) const
If frame pointer or base pointer is clobbered by an instruction, we should spill/restore it around th...
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.
void restoreCalleeSavedRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const CalleeSavedInfo &CS, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
void spillCalleeSavedRegister(MachineBasicBlock &SaveBlock, MachineBasicBlock::iterator MI, const CalleeSavedInfo &CS, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
spillCalleeSavedRegister - Default implementation for spilling a single callee saved register.
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 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 bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
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 void emitRemarks(const MachineFunction &MF, MachineOptimizationRemarkEmitter *ORE) const
This method is called at the end of prolog/epilog code insertion, so targets can emit remarks based o...
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.
virtual bool usesPhysRegsForValues() const
True if the target uses physical regs (as nearly all targets do).
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...
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
DXILDebugInfoMap run(Module &M)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
testing::Matcher< const detail::ErrorHolder & > Failed()
LLVM_ABI void scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS)
Replaces all frame index virtual registers with physical registers.
LLVM_ABI MachineFunctionPass * createPrologEpilogInserterPass()
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI char & PrologEpilogCodeInserterID
PrologEpilogCodeInserter - This pass inserts prolog and epilog code, and eliminates abstract frame re...
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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 formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
DenseMap< MachineBasicBlock *, std::vector< CalleeSavedInfo > > SaveRestorePoints
LLVM_ABI 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.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto reverse_conditionally(ContainerTy &&C, bool ShouldReverse)
Return a range that conditionally reverses C.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.