67#define DEBUG_TYPE "hexagon-pei"
162 if (!HST.getFrameLowering()->hasFP(MF))
173 Register SCSPReg = HST.getSCSPReg();
174 const auto &HRI = *HST.getRegisterInfo();
175 if (!HST.isRegisterReservedByUser(SCSPReg))
180 " to use shadow call stack on Hexagon");
182 const auto &HII = *HST.getInstrInfo();
196 MBB.addLiveIn(SCSPReg);
203 unsigned DwarfSCSReg = HRI.getDwarfRegNum(SCSPReg,
true);
206 assert(DwarfSCSReg < 32 &&
"SCS register should be < 32");
207 const char CFIInst[] = {
208 (
char)dwarf::DW_CFA_val_expression,
211 (
char)(
unsigned)(dwarf::DW_OP_breg0 + DwarfSCSReg),
231 Register SCSPReg = HST.getSCSPReg();
232 const auto &HII = *HST.getInstrInfo();
235 BuildMI(
MBB,
MI,
DL, HII.get(Hexagon::L2_loadri_io), Hexagon::R31)
254 cl::desc(
"Set the number of scavenger slots"),
259 cl::desc(
"Specify O2(not Os) spill func threshold"),
264 cl::desc(
"Specify Os spill func threshold"),
273 cl::desc(
"Enable stack frame shrink wrapping"));
278 cl::desc(
"Max count of stack frame shrink-wraps"));
282 cl::desc(
"Enable long calls for save-restore stubs."),
293 cl::init(std::numeric_limits<unsigned>::max()));
312 char HexagonCallFrameInformation::ID = 0;
316bool HexagonCallFrameInformation::runOnMachineFunction(
MachineFunction &MF) {
317 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
322 HFI.insertCFIInstructions(MF);
327 "Hexagon call frame information",
false,
false)
330 return new HexagonCallFrameInformation();
347 if (!RegNo || SubReg < RegNo)
357 static_assert(Hexagon::R1 > 0,
358 "Assume physical registers are encoded as positive integers");
363 for (
unsigned I = 1,
E = CSI.
size();
I <
E; ++
I) {
384 unsigned Opc =
MI.getOpcode();
386 case Hexagon::PS_alloca:
409 for (
MCPhysReg S : HRI.subregs_inclusive(R))
414 if (MO.isRegMask()) {
419 const uint32_t *BM = MO.getRegMask();
423 if (!(BM[R / 32] & (1u << (R % 32))))
438 unsigned RetOpc =
I->getOpcode();
439 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
461 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
462 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
463 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
464 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
465 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
466 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
467 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
468 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
481 return F.hasOptSize() && !
F.hasMinSize();
493 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB)
const {
494 static unsigned ShrinkCounter = 0;
496 if (MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
505 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
507 MachineDominatorTree MDT;
509 MachinePostDominatorTree MPT;
512 using UnsignedMap = DenseMap<unsigned, unsigned>;
513 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
519 RPO[
I->getNumber()] = RPON++;
525 unsigned BN = RPO[
I.getNumber()];
526 for (MachineBasicBlock *Succ :
I.successors())
528 if (RPO[Succ->getNumber()] <= BN)
535 BitVector CSR(Hexagon::NUM_TARGET_REGS);
536 for (
const MCPhysReg *
P = HRI.getCalleeSavedRegs(&MF); *
P; ++
P)
545 dbgs() <<
"Blocks needing SF: {";
546 for (
auto &
B : SFBlocks)
551 if (SFBlocks.
empty())
555 MachineBasicBlock *DomB = SFBlocks[0];
556 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
561 MachineBasicBlock *PDomB = SFBlocks[0];
562 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
568 dbgs() <<
"Computed dom block: ";
573 dbgs() <<
", computed pdom block: ";
589 LLVM_DEBUG(
dbgs() <<
"PDom block does not post-dominate dom block\n");
612 findShrunkPrologEpilog(MF, PrologB, EpilogB);
614 bool PrologueStubs =
false;
616 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
622 insertAlignaInBlock(*PrologB, AfterCSR);
623 insertPrologueInBlock(*PrologB, PrologueStubs);
631 while (AfterProlog != PrologB->
end() &&
637 updateEntryPaths(MF, *PrologB);
640 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
641 insertEpilogueInBlock(*EpilogB);
644 if (
B.isReturnBlock())
645 insertCSRRestoresInBlock(
B, CSI, HRI);
648 if (
B.isReturnBlock())
649 insertEpilogueInBlock(
B);
667 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
668 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
677 assert(
F.hasFnAttribute(Attribute::NoReturn) &&
678 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
679 !
F.getFunction().hasFnAttribute(Attribute::UWTable));
695 assert(!MFI.hasVarSizedObjects() &&
696 !HST.getRegisterInfo()->hasStackRealignment(MF));
697 return F.hasFnAttribute(Attribute::NoReturn) &&
698 F.hasFnAttribute(Attribute::NoUnwind) &&
699 !
F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
700 MFI.getStackSize() == 0;
703void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &
MBB,
704 bool PrologueStubs)
const {
720 FrameSize = MaxCFA +
alignTo(FrameSize, MaxAlign);
731 SmallVector<MachineInstr *, 4> AdjustRegs;
734 if (
MI.getOpcode() == Hexagon::PS_alloca)
737 for (
auto *
MI : AdjustRegs) {
738 assert((
MI->getOpcode() == Hexagon::PS_alloca) &&
"Expected alloca");
739 expandAlloca(
MI, MF, HII, SP, MaxCF);
740 MI->eraseFromParent();
745 if (MF.getFunction().isVarArg() &&
746 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
748 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
749 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
751 : NumVarArgRegs * 4 + 4;
752 if (RegisterSavedAreaSizePlusPadding > 0) {
755 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
757 .
addImm(-RegisterSavedAreaSizePlusPadding)
762 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
763 for (
int i = HMFI.getFirstNamedArgFrameIndex(),
764 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
769 unsigned LDOpc, STOpc;
773 if (ObjAlign > ObjSize) {
776 else if (ObjSize <= 2)
778 else if (ObjSize <= 4)
780 else if (ObjSize > 4)
784 switch (OpcodeChecker) {
786 LDOpc = Hexagon::L2_loadrb_io;
787 STOpc = Hexagon::S2_storerb_io;
790 LDOpc = Hexagon::L2_loadrh_io;
791 STOpc = Hexagon::S2_storerh_io;
794 LDOpc = Hexagon::L2_loadri_io;
795 STOpc = Hexagon::S2_storeri_io;
799 LDOpc = Hexagon::L2_loadrd_io;
800 STOpc = Hexagon::S2_storerd_io;
804 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
806 int LoadStoreCount = ObjSize / OpcodeChecker;
808 if (ObjSize % OpcodeChecker)
816 NumBytes =
alignTo(NumBytes, ObjAlign);
819 while (
Count < LoadStoreCount) {
821 BuildMI(
MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
823 .
addImm(RegisterSavedAreaSizePlusPadding +
840 NumBytes =
alignTo(NumBytes, 8);
845 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
847 for (
int j = FirstVarArgSavedReg, i = 0;
j < 6; ++
j, ++i) {
848 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
858 insertAllocframe(
MBB, InsertPt, NumBytes);
860 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
868 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
870 }
else if (NumBytes > 0) {
872 auto *TLI = HST.getTargetLowering();
873 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
874 unsigned ProbeSize = 0;
877 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
879 if (NeedsProbing && NumBytes > ProbeSize) {
881 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
886 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
890 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
898void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &
MBB)
const {
912 MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
914 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
915 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
916 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
917 NumBytes += RegisterSavedAreaSizePlusPadding;
920 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
928 unsigned RetOpc = RetI ? RetI->
getOpcode() : 0;
931 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
934 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
937 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
948 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
949 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
950 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
951 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
968 bool NeedsDeallocframe =
true;
969 unsigned PrevOpc = 0;
972 PrevOpc = PrevIt->getOpcode();
973 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
974 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
975 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
976 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
977 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
978 NeedsDeallocframe =
false;
981 if (!MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
983 if (!NeedsDeallocframe) {
988 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
989 PrevOpc != Hexagon::PS_callr_nr)
991 "useRestoreFunction() should have prevented this");
998 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1007 unsigned NewOpc = Hexagon::L4_return;
1008 MachineInstrBuilder NewI =
BuildMI(
MBB, RetI, dl, HII.get(NewOpc))
1018 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
1019 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
1020 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
1025 bool HasRestoreStub =
1027 (
I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1029 Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1030 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1031 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC);
1032 if (!HasRestoreStub)
1033 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1036 if (RegisterSavedAreaSizePlusPadding != 0)
1037 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1039 .
addImm(RegisterSavedAreaSizePlusPadding);
1043 if (NeedsSCS && !HasRestoreStub)
1048void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &
MBB,
1057 const unsigned int ALLOCFRAME_MAX = 16384;
1067 auto *TLI = HST.getTargetLowering();
1068 bool NeedsProbing = TLI->hasInlineStackProbe(MF) && NumBytes > 0;
1069 unsigned ProbeSize = 0;
1072 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1075 if (NeedsProbing && NumBytes > ProbeSize) {
1077 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1085 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
1091 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
1094 }
else if (NumBytes >= ALLOCFRAME_MAX) {
1096 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1105 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1110 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1125 if (
MI.getOpcode() == Hexagon::PS_probed_stackalloc)
1130 auto *TLI = HST.getTargetLowering();
1132 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1138 Register TargetReg =
MI->getOperand(0).getReg();
1145 MF.
insert(InsertPt, LoopMBB);
1148 MF.
insert(InsertPt, ExitMBB);
1169 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi),
1175 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
1181 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
1187 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
1193 BuildMI(*ExitMBB, ExitMBB->
begin(),
DL, HII.get(Hexagon::A2_tfr),
1199 MBB->addSuccessor(LoopMBB);
1204 MI->eraseFromParent();
1211void HexagonFrameLowering::insertAlignaInBlock(
1219 assert(needsAligna(MF) &&
"Unexpected stack align base register");
1224 BuildMI(
MBB, InsertPt,
DL, HII.get(Hexagon::PS_aligna), AP)
1238 for (
unsigned i = 0; i < Worklist.
size(); ++i) {
1239 unsigned BN = Worklist[i];
1242 if (!
MBB.isLiveIn(R.getReg()))
1243 MBB.addLiveIn(R.getReg());
1245 for (
auto &SB :
MBB.successors())
1246 Worklist.
insert(SB->getNumber());
1250bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &
MBB,
1251 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
1252 BitVector &Path)
const {
1255 if (Path[BN] || DoneF[BN])
1263 bool ReachedExit =
false;
1265 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
1271 MachineInstr &RetI =
MBB.
back();
1281 if (ReachedExit && &
MBB != &RestoreB) {
1294static std::optional<MachineBasicBlock::iterator>
1301 auto End =
B.instr_end();
1305 if (!
I.isBundle()) {
1306 if (
I.getOpcode() == Hexagon::S2_allocframe)
1307 return std::next(It);
1311 bool HasCall =
false, HasAllocFrame =
false;
1313 while (++
T !=
End &&
T->isBundled()) {
1314 if (
T->getOpcode() == Hexagon::S2_allocframe)
1315 HasAllocFrame =
true;
1316 else if (
T->isCall())
1320 return HasCall ? It : std::next(It);
1322 return std::nullopt;
1328 insertCFIInstructionsAt(
B, *At);
1343 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1346 bool HasFP = hasFP(MF);
1349 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(),
true);
1350 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(),
true);
1377 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1378 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1379 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1380 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1381 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1382 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1388 auto IfR = [
Reg] (
const CalleeSavedInfo &
C) ->
bool {
1389 return C.getReg() ==
Reg;
1408 getFrameIndexReference(MF,
F->getFrameIdx(), FrameReg).getFixed();
1414 unsigned DwarfReg = HRI.getDwarfRegNum(
Reg,
true);
1426 Register HiReg = HRI.getSubReg(
Reg, Hexagon::isub_hi);
1427 Register LoReg = HRI.getSubReg(
Reg, Hexagon::isub_lo);
1428 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg,
true);
1429 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg,
true);
1445 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1461 if (HasAlloca || HasExtraAlign)
1490 bool Stkchk =
false) {
1491 const char * V4SpillToMemoryFunctions[] = {
1492 "__save_r16_through_r17",
1493 "__save_r16_through_r19",
1494 "__save_r16_through_r21",
1495 "__save_r16_through_r23",
1496 "__save_r16_through_r25",
1497 "__save_r16_through_r27" };
1499 const char * V4SpillToMemoryStkchkFunctions[] = {
1500 "__save_r16_through_r17_stkchk",
1501 "__save_r16_through_r19_stkchk",
1502 "__save_r16_through_r21_stkchk",
1503 "__save_r16_through_r23_stkchk",
1504 "__save_r16_through_r25_stkchk",
1505 "__save_r16_through_r27_stkchk" };
1507 const char * V4SpillFromMemoryFunctions[] = {
1508 "__restore_r16_through_r17_and_deallocframe",
1509 "__restore_r16_through_r19_and_deallocframe",
1510 "__restore_r16_through_r21_and_deallocframe",
1511 "__restore_r16_through_r23_and_deallocframe",
1512 "__restore_r16_through_r25_and_deallocframe",
1513 "__restore_r16_through_r27_and_deallocframe" };
1515 const char * V4SpillFromMemoryTailcallFunctions[] = {
1516 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1517 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1518 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1519 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1520 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1521 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1524 const char **SpillFunc =
nullptr;
1528 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1529 : V4SpillToMemoryFunctions;
1532 SpillFunc = V4SpillFromMemoryFunctions;
1535 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1538 assert(SpillFunc &&
"Unknown spill kind");
1543 return SpillFunc[0];
1545 return SpillFunc[1];
1547 return SpillFunc[2];
1549 return SpillFunc[3];
1551 return SpillFunc[4];
1553 return SpillFunc[5];
1568 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1573 Register SP = HRI.getStackRegister();
1575 Register AP = HMFI.getStackAlignBaseReg();
1590 bool UseFP =
false, UseAP =
false;
1595 if (NoOpt && !HasExtraAlign)
1600 UseFP |= (HasAlloca || HasExtraAlign);
1611 bool HasFP =
hasFP(MF);
1612 assert((HasFP || !UseFP) &&
"This function must have frame pointer");
1638 if (
Offset > 0 && !HasFP)
1653 if (!UseFP && !UseAP)
1654 RealOffset = FrameSize+
Offset;
1660 bool &PrologueStubs)
const {
1665 PrologueStubs =
false;
1670 if (useSpillFunction(MF, CSI)) {
1671 PrologueStubs =
true;
1683 if (StkOvrFlowEnabled) {
1685 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1686 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1688 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1689 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1692 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1693 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1695 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1696 : Hexagon::SAVE_REGISTERS_CALL_V4;
1699 MachineInstr *SaveRegsCall =
1704 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI,
false,
true);
1706 for (
const CalleeSavedInfo &
I : CSI)
1709 for (
const CalleeSavedInfo &
I : CSI) {
1710 MCRegister
Reg =
I.getReg();
1715 int FI =
I.getFrameIdx();
1726bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &
MBB,
1727 const CSIVect &CSI,
const HexagonRegisterInfo &HRI)
const {
1736 if (useRestoreFunction(MF, CSI)) {
1741 auto &HTM =
static_cast<const HexagonTargetMachine&
>(MF.
getTarget());
1742 bool IsPIC = HTM.isPositionIndependent();
1748 MachineInstr *DeallocCall =
nullptr;
1753 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1754 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1756 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1757 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1766 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1767 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1769 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1770 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1771 MachineInstrBuilder MIB =
1775 for (
const MachineOperand &MO :
drop_begin(It->implicit_operands()))
1779 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI,
true,
false);
1783 for (
const CalleeSavedInfo &
I : CSI) {
1784 MCRegister
Reg =
I.getReg();
1786 int FI =
I.getFrameIdx();
1797 unsigned Opc =
MI.getOpcode();
1799 assert((
Opc == Hexagon::ADJCALLSTACKDOWN ||
Opc == Hexagon::ADJCALLSTACKUP) &&
1800 "Cannot handle this call frame pseudo instruction");
1801 return MBB.erase(
I);
1809 auto IsUsed = [&HRI,&MRI] (
Register Reg) ->
bool {
1841 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1868 "AP must be assigned before register allocation");
1873 bool HasResSub =
false;
1899 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1905 for (
int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1943 int64_t MinOffset = 0;
1945 for (
const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1950 MinOffset = std::min(MinOffset, S->Offset);
1952 SRegs[S->Reg] =
false;
1961 unsigned Size =
TRI->getSpillSize(*RC);
1962 int64_t
Off = MinOffset -
Size;
1964 Off &= -Alignment.value();
1966 MinOffset = std::min(MinOffset,
Off);
1972 dbgs() <<
"CS information: {";
1974 int FI =
I.getFrameIdx();
1986 bool MissedReg =
false;
2006 if (!Hexagon::ModRegsRegClass.
contains(DstR) ||
2007 !Hexagon::ModRegsRegClass.
contains(SrcR))
2011 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), TmpR).
add(
MI->getOperand(1));
2012 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), DstR)
2024 if (!
MI->getOperand(0).isFI())
2028 unsigned Opc =
MI->getOpcode();
2030 bool IsKill =
MI->getOperand(2).isKill();
2031 int FI =
MI->getOperand(0).getIndex();
2036 unsigned TfrOpc = (
Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2042 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2053bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &
B,
2055 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2056 MachineInstr *
MI = &*It;
2057 if (!
MI->getOperand(1).isFI())
2061 unsigned Opc =
MI->getOpcode();
2063 int FI =
MI->getOperand(1).getIndex();
2067 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2074 unsigned TfrOpc = (
Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2075 : Hexagon::A2_tfrrcr;
2077 .
addReg(TmpR, RegState::Kill);
2084bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &
B,
2086 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2087 MachineInstr *
MI = &*It;
2088 if (!
MI->getOperand(0).isFI())
2093 bool IsKill =
MI->getOperand(2).isKill();
2094 int FI =
MI->getOperand(0).getIndex();
2095 auto *RC = &Hexagon::HvxVRRegClass;
2104 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2107 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2109 .
addReg(TmpR0, RegState::Kill);
2112 expandStoreVec(
B, std::prev(It), MRI, HII, NewRegs);
2120bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &
B,
2122 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2123 MachineInstr *
MI = &*It;
2124 if (!
MI->getOperand(1).isFI())
2129 int FI =
MI->getOperand(1).getIndex();
2130 auto *RC = &Hexagon::HvxVRRegClass;
2138 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2141 expandLoadVec(
B, std::prev(It), MRI, HII, NewRegs);
2143 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandvrt), DstR)
2144 .
addReg(TmpR1, RegState::Kill)
2145 .
addReg(TmpR0, RegState::Kill);
2153bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &
B,
2155 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2158 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2159 MachineInstr *
MI = &*It;
2160 if (!
MI->getOperand(0).isFI())
2167 LivePhysRegs LPR(HRI);
2170 for (
auto R =
B.begin(); R != It; ++R) {
2172 LPR.stepForward(*R, Clobbers);
2177 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2178 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2179 bool IsKill =
MI->getOperand(2).isKill();
2180 int FI =
MI->getOperand(0).getIndex();
2182 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2183 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2188 if (LPR.contains(SrcLo)) {
2189 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2190 : Hexagon::V6_vS32Ub_ai;
2199 if (LPR.contains(SrcHi)) {
2200 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2201 : Hexagon::V6_vS32Ub_ai;
2213bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &
B,
2215 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2218 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2219 MachineInstr *
MI = &*It;
2220 if (!
MI->getOperand(1).isFI())
2225 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2226 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2227 int FI =
MI->getOperand(1).getIndex();
2229 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2230 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2235 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2236 : Hexagon::V6_vL32Ub_ai;
2243 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2244 : Hexagon::V6_vL32Ub_ai;
2254bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &
B,
2256 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2259 MachineInstr *
MI = &*It;
2260 if (!
MI->getOperand(0).isFI())
2263 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2266 bool IsKill =
MI->getOperand(2).isKill();
2267 int FI =
MI->getOperand(0).getIndex();
2269 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2271 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2272 : Hexagon::V6_vS32Ub_ai;
2283bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &
B,
2285 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2288 MachineInstr *
MI = &*It;
2289 if (!
MI->getOperand(1).isFI())
2292 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2295 int FI =
MI->getOperand(1).getIndex();
2297 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2299 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2300 : Hexagon::V6_vL32Ub_ai;
2311 SmallVectorImpl<Register> &NewRegs)
const {
2312 auto &HII = *MF.
getSubtarget<HexagonSubtarget>().getInstrInfo();
2316 for (
auto &
B : MF) {
2319 for (
auto I =
B.begin(),
E =
B.end();
I !=
E;
I = NextI) {
2320 MachineInstr *
MI = &*
I;
2321 NextI = std::next(
I);
2322 unsigned Opc =
MI->getOpcode();
2325 case TargetOpcode::COPY:
2326 Changed |= expandCopy(
B,
I, MRI, HII, NewRegs);
2328 case Hexagon::STriw_pred:
2329 case Hexagon::STriw_ctr:
2330 Changed |= expandStoreInt(
B,
I, MRI, HII, NewRegs);
2332 case Hexagon::LDriw_pred:
2333 case Hexagon::LDriw_ctr:
2334 Changed |= expandLoadInt(
B,
I, MRI, HII, NewRegs);
2336 case Hexagon::PS_vstorerq_ai:
2337 Changed |= expandStoreVecPred(
B,
I, MRI, HII, NewRegs);
2339 case Hexagon::PS_vloadrq_ai:
2340 Changed |= expandLoadVecPred(
B,
I, MRI, HII, NewRegs);
2342 case Hexagon::PS_vloadrw_ai:
2343 Changed |= expandLoadVec2(
B,
I, MRI, HII, NewRegs);
2345 case Hexagon::PS_vstorerw_ai:
2346 Changed |= expandStoreVec2(
B,
I, MRI, HII, NewRegs);
2360 SavedRegs.
resize(HRI.getNumRegs());
2374 assert(AP.
isValid() &&
"AP must be assigned before register allocation");
2380 expandSpillMacros(MF, NewRegs);
2382 optimizeSpillSlots(MF, NewRegs);
2386 if (!NewRegs.
empty() || mayOverflowFrameOffset(MF)) {
2392 SpillRCs.
insert(&Hexagon::IntRegsRegClass);
2397 for (
const auto *RC : SpillRCs) {
2401 switch (RC->
getID()) {
2402 case Hexagon::IntRegsRegClassID:
2405 case Hexagon::HvxQRRegClassID:
2409 unsigned S = HRI.getSpillSize(*RC);
2410 Align A = HRI.getSpillAlign(*RC);
2411 for (
unsigned i = 0; i < Num; i++) {
2413 RS->addScavengingFrameIndex(NewFI);
2430 auto F = DeadMap.find({Reg,0});
2431 if (
F == DeadMap.end())
2433 for (
auto &DR :
F->second)
2434 if (DR.contains(FIR))
2439 for (
Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2454 SmallVectorImpl<Register> &VRegs)
const {
2456 auto &HII = *HST.getInstrInfo();
2457 auto &HRI = *HST.getRegisterInfo();
2459 HexagonBlockRanges HBR(MF);
2461 using BlockIndexMap =
2462 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2463 using BlockRangeMap =
2464 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2465 using IndexType = HexagonBlockRanges::IndexType;
2472 SlotInfo() =
default;
2475 BlockIndexMap BlockIndexes;
2476 SmallSet<int,4> BadFIs;
2477 std::map<int,SlotInfo> FIRangeMap;
2486 if (HaveRC ==
nullptr || HaveRC == NewRC)
2491 if (NewRC->hasSubClassEq(HaveRC))
2498 for (
auto &
B : MF) {
2499 std::map<int,IndexType> LastStore, LastLoad;
2500 auto P = BlockIndexes.emplace(&
B, HexagonBlockRanges::InstrIndexMap(
B));
2501 auto &IndexMap =
P.first->second;
2503 << IndexMap <<
'\n');
2505 for (
auto &In :
B) {
2509 if (
In.isDebugInstr())
2512 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2513 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2527 int TFI =
Load ? LFI : SFI;
2528 unsigned AM = HII.getAddrMode(In);
2529 SlotInfo &
SI = FIRangeMap[TFI];
2533 unsigned OpNum =
Load ? 0 : 2;
2534 auto *RC = HII.getRegClass(
In.getDesc(), OpNum);
2535 RC = getCommonRC(
SI.RC, RC);
2543 unsigned S = HII.getMemAccessSize(In);
2544 if (
SI.Size != 0 &&
SI.Size != S)
2550 for (
auto *Mo :
In.memoperands()) {
2551 if (!Mo->isVolatile() && !Mo->isAtomic())
2562 for (
unsigned i = 0, n =
In.getNumOperands(); i < n; ++i) {
2563 const MachineOperand &
Op =
In.getOperand(i);
2566 int FI =
Op.getIndex();
2569 if (i+1 >= n || !
In.getOperand(i+1).isImm() ||
2570 In.getOperand(i+1).getImm() != 0)
2572 if (BadFIs.
count(FI))
2576 auto &
LS = LastStore[FI];
2577 auto &LL = LastLoad[FI];
2579 if (LS == IndexType::None)
2580 LS = IndexType::Entry;
2583 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2584 if (LS != IndexType::None)
2585 RL.
add(LS, LL,
false,
false);
2586 else if (LL != IndexType::None)
2587 RL.
add(IndexType::Entry, LL,
false,
false);
2588 LL = IndexType::None;
2596 for (
auto &
I : LastLoad) {
2597 IndexType LL =
I.second;
2598 if (LL == IndexType::None)
2600 auto &RL = FIRangeMap[
I.first].Map[&
B];
2601 IndexType &
LS = LastStore[
I.first];
2602 if (LS != IndexType::None)
2603 RL.
add(LS, LL,
false,
false);
2605 RL.
add(IndexType::Entry, LL,
false,
false);
2606 LS = IndexType::None;
2608 for (
auto &
I : LastStore) {
2609 IndexType
LS =
I.second;
2610 if (LS == IndexType::None)
2612 auto &RL = FIRangeMap[
I.first].Map[&
B];
2613 RL.
add(LS, IndexType::None,
false,
false);
2618 for (
auto &
P : FIRangeMap) {
2619 dbgs() <<
"fi#" <<
P.first;
2620 if (BadFIs.
count(
P.first))
2623 if (
P.second.RC !=
nullptr)
2624 dbgs() << HRI.getRegClassName(
P.second.RC) <<
'\n';
2626 dbgs() <<
"<null>\n";
2627 for (
auto &R :
P.second.Map)
2636 SmallSet<int,4> LoxFIs;
2638 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2640 for (
auto &
P : FIRangeMap) {
2642 if (BadFIs.
count(
P.first))
2644 for (
auto &
B : MF) {
2645 auto F =
P.second.Map.find(&
B);
2647 if (
F ==
P.second.Map.end() ||
F->second.empty())
2649 HexagonBlockRanges::IndexRange &
IR =
F->second.front();
2650 if (
IR.start() == IndexType::Entry)
2651 LoxFIs.insert(
P.first);
2652 BlockFIMap[&
B].push_back(
P.first);
2657 dbgs() <<
"Block-to-FI map (* -- live-on-exit):\n";
2658 for (
auto &
P : BlockFIMap) {
2659 auto &FIs =
P.second;
2663 for (
auto I : FIs) {
2664 dbgs() <<
" fi#" <<
I;
2665 if (LoxFIs.count(
I))
2677 for (
auto &
B : MF) {
2678 auto F = BlockIndexes.find(&
B);
2679 assert(
F != BlockIndexes.end());
2680 HexagonBlockRanges::InstrIndexMap &IM =
F->second;
2684 << HexagonBlockRanges::PrintRangeMap(
DM, HRI));
2686 for (
auto FI : BlockFIMap[&
B]) {
2687 if (BadFIs.
count(FI))
2690 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2691 for (
auto &
Range : RL) {
2693 if (!IndexType::isInstr(
Range.start()) ||
2694 !IndexType::isInstr(
Range.end()))
2698 assert(
SI.mayStore() &&
"Unexpected start instruction");
2700 MachineOperand &SrcOp =
SI.getOperand(2);
2702 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.
getReg(),
2704 auto *RC = HII.getRegClass(
SI.getDesc(), 2);
2721 MachineInstr *CopyIn =
nullptr;
2722 if (SrcRR.
Reg != FoundR || SrcRR.
Sub != 0) {
2724 CopyIn =
BuildMI(
B, StartIt,
DL, HII.get(TargetOpcode::COPY), FoundR)
2730 if (LoxFIs.count(FI) && (&
Range == &RL.back())) {
2733 SrcOp.
setReg(HRI.getSubReg(FoundR, SR));
2745 for (
auto It = StartIt; It != EndIt; It = NextIt) {
2746 MachineInstr &
MI = *It;
2747 NextIt = std::next(It);
2749 if (!HII.isLoadFromStackSlot(
MI, TFI) || TFI != FI)
2752 assert(
MI.getOperand(0).getSubReg() == 0);
2753 MachineInstr *CopyOut =
nullptr;
2754 if (DstR != FoundR) {
2756 unsigned MemSize = HII.getMemAccessSize(
MI);
2758 unsigned CopyOpc = TargetOpcode::COPY;
2759 if (HII.isSignExtendingLoad(
MI))
2760 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2761 else if (HII.isZeroExtendingLoad(
MI))
2762 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2763 CopyOut =
BuildMI(
B, It,
DL, HII.get(CopyOpc), DstR)
2771 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2779void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
MachineFunction &MF,
2780 const HexagonInstrInfo &HII,
2782 MachineBasicBlock &MB = *AI->
getParent();
2792 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2794 if (!NeedsProbing) {
2818 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2822 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), SP)
2860 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2865 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_sub), Rd)
2871 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2880 MF.
insert(InsertPt, LoopMBB);
2882 MF.
insert(InsertPt, ExitMBB);
2893 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2898 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
2904 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
2910 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
2919 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
2923 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_addi), Rd)
2951void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(
MachineInstr *
MI,
2952 const CSIVect &CSI,
bool IsDef,
bool IsKill)
const {
2963 const CSIVect &CSI)
const {
2976 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2979 if (!Hexagon::DoubleRegsRegClass.
contains(R))
2983 int F = Regs.find_first();
2984 if (
F != Hexagon::D8)
2987 int N = Regs.find_next(
F);
2988 if (
N >= 0 &&
N !=
F+1)
2997 const CSIVect &CSI)
const {
2998 if (shouldInlineCSR(MF, CSI))
3000 unsigned NumCSI = CSI.size();
3019 if (HST.getSCSPReg().id() <= MaxReg.id())
3025 return Threshold < NumCSI;
3028bool HexagonFrameLowering::useRestoreFunction(
const MachineFunction &MF,
3029 const CSIVect &CSI)
const {
3030 if (shouldInlineCSR(MF, CSI))
3043 unsigned NumCSI = CSI.size();
3049 return Threshold < NumCSI;
3052bool HexagonFrameLowering::mayOverflowFrameOffset(
MachineFunction &MF)
const {
3057 if (HST.useHVXOps() && StackSize > 256)
3064 bool HasImmStack =
false;
3065 unsigned MinLS = ~0
u;
3067 for (
const MachineBasicBlock &
B : MF) {
3068 for (
const MachineInstr &
MI :
B) {
3070 switch (
MI.getOpcode()) {
3071 case Hexagon::S4_storeirit_io:
3072 case Hexagon::S4_storeirif_io:
3073 case Hexagon::S4_storeiri_io:
3076 case Hexagon::S4_storeirht_io:
3077 case Hexagon::S4_storeirhf_io:
3078 case Hexagon::S4_storeirh_io:
3081 case Hexagon::S4_storeirbt_io:
3082 case Hexagon::S4_storeirbf_io:
3083 case Hexagon::S4_storeirb_io:
3084 if (
MI.getOperand(0).isFI())
3086 MinLS = std::min(MinLS, LS);
3100struct HexagonFrameSortingObject {
3101 bool IsValid =
false;
3107struct HexagonFrameSortingComparator {
3108 inline bool operator()(
const HexagonFrameSortingObject &
A,
3109 const HexagonFrameSortingObject &
B)
const {
3110 return std::make_tuple(!
A.IsValid,
A.ObjectAlignment,
A.Size) <
3111 std::make_tuple(!
B.IsValid,
B.ObjectAlignment,
B.Size);
3121 if (ObjectsToAllocate.
empty())
3125 int NObjects = ObjectsToAllocate.
size();
3133 if (i != ObjectsToAllocate[j])
3144 SortingObjects[i].IsValid =
true;
3145 SortingObjects[i].Index = i;
3155 for (
auto &Obj : SortingObjects) {
3158 ObjectsToAllocate[--i] = Obj.Index;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static MachineInstr * getReturn(MachineBasicBlock &MBB)
Returns the "return" instruction from this block, or nullptr if there isn't any.
static cl::opt< unsigned > ShrinkLimit("shrink-frame-limit", cl::init(std::numeric_limits< unsigned >::max()), cl::Hidden, cl::desc("Max count of stack frame shrink-wraps"))
static bool isOptNone(const MachineFunction &MF)
static cl::opt< int > SpillFuncThreshold("spill-func-threshold", cl::Hidden, cl::desc("Specify O2(not Os) spill func threshold"), cl::init(6))
static std::optional< MachineBasicBlock::iterator > findCFILocation(MachineBasicBlock &B)
static cl::opt< bool > EliminateFramePointer("hexagon-fp-elim", cl::init(true), cl::Hidden, cl::desc("Refrain from using FP whenever possible"))
static bool enableAllocFrameElim(const MachineFunction &MF)
static const char * getSpillFunctionFor(Register MaxReg, SpillKind SpillType, bool Stkchk=false)
static bool hasReturn(const MachineBasicBlock &MBB)
Returns true if MBB contains an instruction that returns.
static cl::opt< bool > EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden, cl::desc("Enable long calls for save-restore stubs."), cl::init(false))
static bool needToReserveScavengingSpillSlots(MachineFunction &MF, const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC)
Returns true if there are no caller-saved registers available in class RC.
static bool isOptSize(const MachineFunction &MF)
static Register getMax32BitSubRegister(Register Reg, const TargetRegisterInfo &TRI, bool hireg=true)
Map a register pair Reg to the subregister that has the greater "number", i.e.
static cl::opt< int > SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden, cl::desc("Specify Os spill func threshold"), cl::init(1))
static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR, const HexagonRegisterInfo &HRI)
Checks if the basic block contains any instruction that needs a stack frame to be already in place.
static cl::opt< bool > DisableDeallocRet("disable-hexagon-dealloc-ret", cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"))
static cl::opt< bool > EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden, cl::desc("Enable stack frame shrink wrapping"))
static bool hasTailCall(const MachineBasicBlock &MBB)
Returns true if MBB has a machine instructions that indicates a tail call in the block.
static cl::opt< unsigned > NumberScavengerSlots("number-scavenger-slots", cl::Hidden, cl::desc("Set the number of scavenger slots"), cl::init(2))
static Register getMaxCalleeSavedReg(ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo &TRI)
Returns the callee saved register with the largest id in the vector.
static bool isMinSize(const MachineFunction &MF)
static cl::opt< unsigned > SpillOptMax("spill-opt-max", cl::Hidden, cl::init(std::numeric_limits< unsigned >::max()))
static unsigned SpillOptCount
static void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI)
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static bool isRestoreCall(unsigned Opc)
static cl::opt< bool > OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden, cl::init(true), cl::desc("Optimize spill slots"))
static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static cl::opt< bool > EnableStackOVFSanitizer("enable-stackovf-sanitizer", cl::Hidden, cl::desc("Enable runtime checks for stack overflow."), cl::init(false))
Legalize the Machine IR a function s Machine IR
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file declares the machine register scavenger class.
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
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.
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.
Helper class for creating CFI instructions and inserting them into MIR.
void buildEscape(StringRef Bytes, StringRef Comment="") const
void buildRestore(MCRegister Reg) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool hasOptNone() const
Do not optimize this function (-O0).
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI)
IndexType getIndex(MachineInstr *MI) const
MachineInstr * getInstr(IndexType Idx) const
void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd)
void insertCFIInstructions(MachineFunction &MF) const
bool hasFPImpl(const MachineFunction &MF) const override
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Perform most of the PEI work here:
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Replace a StackProbe stub (if any) with the actual probe code inline.
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
bool needsAligna(const MachineFunction &MF) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
const HexagonRegisterInfo & getRegisterInfo() const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Hexagon target-specific information for each MachineFunction.
Register getStackAlignBaseReg() const
bool isEHReturnCalleeSaveReg(Register Reg) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
bool isEnvironmentMusl() const
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getID() const
getID() - Return the register class ID number.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
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.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
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.
bool hasCalls() const
Return true if the current function has any function calls.
Align getMaxAlign() const
Return alignment of this function's frame.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
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.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
BasicBlockListType::iterator iterator
bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
instr_iterator getInstrIterator() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isReturn(QueryType Type=AnyInBundle) const
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
mop_range implicit_operands()
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
LLVM_ABI MachineBasicBlock * findNearestCommonDominator(ArrayRef< MachineBasicBlock * > Blocks) const
Returns the nearest common dominator of the given blocks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getFixed() const
Returns the fixed component of the stack.
Represent a constant reference to a string, i.e.
LLVM_ABI std::string lower() const
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const TargetRegisterInfo & getRegisterInfo() const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
bool isPositionIndependent() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
unsigned getPosition() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void stable_sort(R &&Range)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonCallFrameInformation()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
MaybeAlign getStackAlign(const Function &F, unsigned Index)
@ End
Run the machine verifier once, at the end of the pipeline.
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
static RegisterSet expandToSubRegs(RegisterRef R, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
std::map< RegisterRef, RangeList > RegToRangeMap
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.