68#define DEBUG_TYPE "hexagon-pei"
163 if (!HST.getFrameLowering()->hasFP(MF))
174 Register SCSPReg = HST.getSCSPReg();
175 const auto &HRI = *HST.getRegisterInfo();
176 if (!HST.isRegisterReservedByUser(SCSPReg))
181 " to use shadow call stack on Hexagon");
183 const auto &HII = *HST.getInstrInfo();
197 MBB.addLiveIn(SCSPReg);
204 unsigned DwarfSCSReg = HRI.getDwarfRegNum(SCSPReg,
true);
207 assert(DwarfSCSReg < 32 &&
"SCS register should be < 32");
208 const char CFIInst[] = {
209 (
char)dwarf::DW_CFA_val_expression,
212 (
char)(
unsigned)(dwarf::DW_OP_breg0 + DwarfSCSReg),
232 Register SCSPReg = HST.getSCSPReg();
233 const auto &HII = *HST.getInstrInfo();
236 BuildMI(
MBB,
MI,
DL, HII.get(Hexagon::L2_loadri_io), Hexagon::R31)
255 cl::desc(
"Set the number of scavenger slots"),
260 cl::desc(
"Specify O2(not Os) spill func threshold"),
265 cl::desc(
"Specify Os spill func threshold"),
274 cl::desc(
"Enable stack frame shrink wrapping"));
279 cl::desc(
"Max count of stack frame shrink-wraps"));
283 cl::desc(
"Enable long calls for save-restore stubs."),
294 cl::init(std::numeric_limits<unsigned>::max()));
313 char HexagonCallFrameInformation::ID = 0;
317bool HexagonCallFrameInformation::runOnMachineFunction(
MachineFunction &MF) {
318 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
323 HFI.insertCFIInstructions(MF);
328 "Hexagon call frame information",
false,
false)
331 return new HexagonCallFrameInformation();
348 if (!RegNo || SubReg < RegNo)
358 static_assert(Hexagon::R1 > 0,
359 "Assume physical registers are encoded as positive integers");
364 for (
unsigned I = 1,
E = CSI.
size();
I <
E; ++
I) {
385 unsigned Opc =
MI.getOpcode();
387 case Hexagon::PS_alloca:
410 for (
MCPhysReg S : HRI.subregs_inclusive(R))
415 if (MO.isRegMask()) {
420 const uint32_t *BM = MO.getRegMask();
424 if (!(BM[R / 32] & (1u << (R % 32))))
439 unsigned RetOpc =
I->getOpcode();
440 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
462 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
463 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
464 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
465 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
466 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
467 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
468 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
469 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
482 return F.hasOptSize() && !
F.hasMinSize();
494 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB)
const {
495 static unsigned ShrinkCounter = 0;
497 if (MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
506 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
508 MachineDominatorTree MDT;
510 MachinePostDominatorTree MPT;
513 using UnsignedMap = DenseMap<unsigned, unsigned>;
514 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
520 RPO[
I->getNumber()] = RPON++;
526 unsigned BN = RPO[
I.getNumber()];
527 for (MachineBasicBlock *Succ :
I.successors())
529 if (RPO[Succ->getNumber()] <= BN)
536 BitVector CSR(Hexagon::NUM_TARGET_REGS);
537 for (
const MCPhysReg *
P = HRI.getCalleeSavedRegs(&MF); *
P; ++
P)
546 dbgs() <<
"Blocks needing SF: {";
547 for (
auto &
B : SFBlocks)
552 if (SFBlocks.
empty())
556 MachineBasicBlock *DomB = SFBlocks[0];
557 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
562 MachineBasicBlock *PDomB = SFBlocks[0];
563 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
569 dbgs() <<
"Computed dom block: ";
574 dbgs() <<
", computed pdom block: ";
590 LLVM_DEBUG(
dbgs() <<
"PDom block does not post-dominate dom block\n");
613 findShrunkPrologEpilog(MF, PrologB, EpilogB);
615 bool PrologueStubs =
false;
617 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
623 insertAlignaInBlock(*PrologB, AfterCSR);
624 insertPrologueInBlock(*PrologB, PrologueStubs);
632 while (AfterProlog != PrologB->
end() &&
638 updateEntryPaths(MF, *PrologB);
641 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
642 insertEpilogueInBlock(*EpilogB);
645 if (
B.isReturnBlock())
646 insertCSRRestoresInBlock(
B, CSI, HRI);
649 if (
B.isReturnBlock())
650 insertEpilogueInBlock(
B);
668 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
669 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
678 assert(
F.hasFnAttribute(Attribute::NoReturn) &&
679 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
680 !
F.getFunction().hasFnAttribute(Attribute::UWTable));
696 assert(!MFI.hasVarSizedObjects() &&
697 !HST.getRegisterInfo()->hasStackRealignment(MF));
698 return F.hasFnAttribute(Attribute::NoReturn) &&
699 F.hasFnAttribute(Attribute::NoUnwind) &&
700 !
F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
701 MFI.getStackSize() == 0;
704void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &
MBB,
705 bool PrologueStubs)
const {
721 FrameSize = MaxCFA +
alignTo(FrameSize, MaxAlign);
732 SmallVector<MachineInstr *, 4> AdjustRegs;
735 if (
MI.getOpcode() == Hexagon::PS_alloca)
738 for (
auto *
MI : AdjustRegs) {
739 assert((
MI->getOpcode() == Hexagon::PS_alloca) &&
"Expected alloca");
740 expandAlloca(
MI, MF, HII, SP, MaxCF);
741 MI->eraseFromParent();
746 if (MF.getFunction().isVarArg() &&
747 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
749 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
750 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
752 : NumVarArgRegs * 4 + 4;
753 if (RegisterSavedAreaSizePlusPadding > 0) {
756 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
758 .
addImm(-RegisterSavedAreaSizePlusPadding)
763 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
764 for (
int i = HMFI.getFirstNamedArgFrameIndex(),
765 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
770 unsigned LDOpc, STOpc;
774 if (ObjAlign > ObjSize) {
777 else if (ObjSize <= 2)
779 else if (ObjSize <= 4)
781 else if (ObjSize > 4)
785 switch (OpcodeChecker) {
787 LDOpc = Hexagon::L2_loadrb_io;
788 STOpc = Hexagon::S2_storerb_io;
791 LDOpc = Hexagon::L2_loadrh_io;
792 STOpc = Hexagon::S2_storerh_io;
795 LDOpc = Hexagon::L2_loadri_io;
796 STOpc = Hexagon::S2_storeri_io;
800 LDOpc = Hexagon::L2_loadrd_io;
801 STOpc = Hexagon::S2_storerd_io;
805 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
807 int LoadStoreCount = ObjSize / OpcodeChecker;
809 if (ObjSize % OpcodeChecker)
817 NumBytes =
alignTo(NumBytes, ObjAlign);
820 while (
Count < LoadStoreCount) {
822 BuildMI(
MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
824 .
addImm(RegisterSavedAreaSizePlusPadding +
841 NumBytes =
alignTo(NumBytes, 8);
846 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
848 for (
int j = FirstVarArgSavedReg, i = 0;
j < 6; ++
j, ++i) {
849 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
859 insertAllocframe(
MBB, InsertPt, NumBytes);
861 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
869 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
871 }
else if (NumBytes > 0) {
873 auto *TLI = HST.getTargetLowering();
874 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
875 unsigned ProbeSize = 0;
878 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
880 if (NeedsProbing && NumBytes > ProbeSize) {
882 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
887 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
891 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
899void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &
MBB)
const {
913 MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
915 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
916 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
917 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
918 NumBytes += RegisterSavedAreaSizePlusPadding;
921 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
929 unsigned RetOpc = RetI ? RetI->
getOpcode() : 0;
932 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
935 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
938 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
949 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
950 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
951 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
952 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
969 bool NeedsDeallocframe =
true;
970 unsigned PrevOpc = 0;
973 PrevOpc = PrevIt->getOpcode();
974 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
975 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
976 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
977 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
978 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
979 NeedsDeallocframe =
false;
982 if (!MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
984 if (!NeedsDeallocframe) {
989 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
990 PrevOpc != Hexagon::PS_callr_nr)
992 "useRestoreFunction() should have prevented this");
999 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1008 unsigned NewOpc = Hexagon::L4_return;
1009 MachineInstr *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)
1491 bool Stkchk =
false) {
1492 const char * V4SpillToMemoryFunctions[] = {
1493 "__save_r16_through_r17",
1494 "__save_r16_through_r19",
1495 "__save_r16_through_r21",
1496 "__save_r16_through_r23",
1497 "__save_r16_through_r25",
1498 "__save_r16_through_r27" };
1500 const char * V4SpillToMemoryStkchkFunctions[] = {
1501 "__save_r16_through_r17_stkchk",
1502 "__save_r16_through_r19_stkchk",
1503 "__save_r16_through_r21_stkchk",
1504 "__save_r16_through_r23_stkchk",
1505 "__save_r16_through_r25_stkchk",
1506 "__save_r16_through_r27_stkchk" };
1508 const char * V4SpillFromMemoryFunctions[] = {
1509 "__restore_r16_through_r17_and_deallocframe",
1510 "__restore_r16_through_r19_and_deallocframe",
1511 "__restore_r16_through_r21_and_deallocframe",
1512 "__restore_r16_through_r23_and_deallocframe",
1513 "__restore_r16_through_r25_and_deallocframe",
1514 "__restore_r16_through_r27_and_deallocframe" };
1516 const char * V4SpillFromMemoryTailcallFunctions[] = {
1517 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1518 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1519 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1520 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1521 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1522 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1525 const char **SpillFunc =
nullptr;
1529 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1530 : V4SpillToMemoryFunctions;
1533 SpillFunc = V4SpillFromMemoryFunctions;
1536 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1539 assert(SpillFunc &&
"Unknown spill kind");
1544 return SpillFunc[0];
1546 return SpillFunc[1];
1548 return SpillFunc[2];
1550 return SpillFunc[3];
1552 return SpillFunc[4];
1554 return SpillFunc[5];
1569 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1574 Register SP = HRI.getStackRegister();
1576 Register AP = HMFI.getStackAlignBaseReg();
1591 bool UseFP =
false, UseAP =
false;
1596 if (NoOpt && !HasExtraAlign)
1601 UseFP |= (HasAlloca || HasExtraAlign);
1612 bool HasFP =
hasFP(MF);
1613 assert((HasFP || !UseFP) &&
"This function must have frame pointer");
1639 if (
Offset > 0 && !HasFP)
1654 if (!UseFP && !UseAP)
1655 RealOffset = FrameSize+
Offset;
1661 bool &PrologueStubs)
const {
1666 PrologueStubs =
false;
1671 if (useSpillFunction(MF, CSI)) {
1672 PrologueStubs =
true;
1684 if (StkOvrFlowEnabled) {
1686 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1687 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1689 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1690 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1693 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1694 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1696 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1697 : Hexagon::SAVE_REGISTERS_CALL_V4;
1700 MachineInstr *SaveRegsCall =
1705 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI,
false,
true);
1707 for (
const CalleeSavedInfo &
I : CSI)
1710 for (
const CalleeSavedInfo &
I : CSI) {
1711 MCRegister
Reg =
I.getReg();
1716 int FI =
I.getFrameIdx();
1727bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &
MBB,
1728 const CSIVect &CSI,
const HexagonRegisterInfo &HRI)
const {
1737 if (useRestoreFunction(MF, CSI)) {
1742 auto &HTM =
static_cast<const HexagonTargetMachine&
>(MF.
getTarget());
1743 bool IsPIC = HTM.isPositionIndependent();
1749 MachineInstr *DeallocCall =
nullptr;
1754 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1755 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1757 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1758 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1767 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1768 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1770 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1771 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1777 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI,
true,
false);
1781 for (
const CalleeSavedInfo &
I : CSI) {
1782 MCRegister
Reg =
I.getReg();
1784 int FI =
I.getFrameIdx();
1795 unsigned Opc =
MI.getOpcode();
1797 assert((
Opc == Hexagon::ADJCALLSTACKDOWN ||
Opc == Hexagon::ADJCALLSTACKUP) &&
1798 "Cannot handle this call frame pseudo instruction");
1799 return MBB.erase(
I);
1807 auto IsUsed = [&HRI,&MRI] (
Register Reg) ->
bool {
1839 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1866 "AP must be assigned before register allocation");
1871 bool HasResSub =
false;
1897 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1903 for (
int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1941 int64_t MinOffset = 0;
1943 for (
const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1948 MinOffset = std::min(MinOffset, S->Offset);
1950 SRegs[S->Reg] =
false;
1959 unsigned Size =
TRI->getSpillSize(*RC);
1960 int64_t Off = MinOffset -
Size;
1962 Off &= -Alignment.value();
1964 MinOffset = std::min(MinOffset, Off);
1970 dbgs() <<
"CS information: {";
1972 int FI =
I.getFrameIdx();
1984 bool MissedReg =
false;
2004 if (!Hexagon::ModRegsRegClass.
contains(DstR) ||
2005 !Hexagon::ModRegsRegClass.
contains(SrcR))
2009 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), TmpR).
add(
MI->getOperand(1));
2010 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), DstR)
2022 if (!
MI->getOperand(0).isFI())
2026 unsigned Opc =
MI->getOpcode();
2028 bool IsKill =
MI->getOperand(2).isKill();
2029 int FI =
MI->getOperand(0).getIndex();
2034 unsigned TfrOpc = (
Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2040 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2051bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &
B,
2053 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2054 MachineInstr *
MI = &*It;
2055 if (!
MI->getOperand(1).isFI())
2059 unsigned Opc =
MI->getOpcode();
2061 int FI =
MI->getOperand(1).getIndex();
2065 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2072 unsigned TfrOpc = (
Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2073 : Hexagon::A2_tfrrcr;
2075 .
addReg(TmpR, RegState::Kill);
2082bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &
B,
2084 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2085 MachineInstr *
MI = &*It;
2086 if (!
MI->getOperand(0).isFI())
2091 bool IsKill =
MI->getOperand(2).isKill();
2092 int FI =
MI->getOperand(0).getIndex();
2093 auto *RC = &Hexagon::HvxVRRegClass;
2102 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2105 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2107 .
addReg(TmpR0, RegState::Kill);
2110 expandStoreVec(
B, std::prev(It), MRI, HII, NewRegs);
2118bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &
B,
2120 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2121 MachineInstr *
MI = &*It;
2122 if (!
MI->getOperand(1).isFI())
2127 int FI =
MI->getOperand(1).getIndex();
2128 auto *RC = &Hexagon::HvxVRRegClass;
2136 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2139 expandLoadVec(
B, std::prev(It), MRI, HII, NewRegs);
2141 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandvrt), DstR)
2142 .
addReg(TmpR1, RegState::Kill)
2143 .
addReg(TmpR0, RegState::Kill);
2151bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &
B,
2153 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2156 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2157 MachineInstr *
MI = &*It;
2158 if (!
MI->getOperand(0).isFI())
2165 LivePhysRegs LPR(HRI);
2168 for (
auto R =
B.begin(); R != It; ++R) {
2170 LPR.stepForward(*R, Clobbers);
2175 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2176 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2177 bool IsKill =
MI->getOperand(2).isKill();
2178 int FI =
MI->getOperand(0).getIndex();
2180 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2181 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2186 if (LPR.contains(SrcLo)) {
2187 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2188 : Hexagon::V6_vS32Ub_ai;
2197 if (LPR.contains(SrcHi)) {
2198 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2199 : Hexagon::V6_vS32Ub_ai;
2211bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &
B,
2213 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2216 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2217 MachineInstr *
MI = &*It;
2218 if (!
MI->getOperand(1).isFI())
2223 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2224 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2225 int FI =
MI->getOperand(1).getIndex();
2227 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2228 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2233 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2234 : Hexagon::V6_vL32Ub_ai;
2241 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2242 : Hexagon::V6_vL32Ub_ai;
2252bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &
B,
2254 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2257 MachineInstr *
MI = &*It;
2258 if (!
MI->getOperand(0).isFI())
2261 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2264 bool IsKill =
MI->getOperand(2).isKill();
2265 int FI =
MI->getOperand(0).getIndex();
2267 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2269 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2270 : Hexagon::V6_vS32Ub_ai;
2281bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &
B,
2283 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2286 MachineInstr *
MI = &*It;
2287 if (!
MI->getOperand(1).isFI())
2290 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2293 int FI =
MI->getOperand(1).getIndex();
2295 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2297 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2298 : Hexagon::V6_vL32Ub_ai;
2309 SmallVectorImpl<Register> &NewRegs)
const {
2310 auto &HII = *MF.
getSubtarget<HexagonSubtarget>().getInstrInfo();
2314 for (
auto &
B : MF) {
2317 for (
auto I =
B.begin(),
E =
B.end();
I !=
E;
I = NextI) {
2318 MachineInstr *
MI = &*
I;
2319 NextI = std::next(
I);
2320 unsigned Opc =
MI->getOpcode();
2323 case TargetOpcode::COPY:
2324 Changed |= expandCopy(
B,
I, MRI, HII, NewRegs);
2326 case Hexagon::STriw_pred:
2327 case Hexagon::STriw_ctr:
2328 Changed |= expandStoreInt(
B,
I, MRI, HII, NewRegs);
2330 case Hexagon::LDriw_pred:
2331 case Hexagon::LDriw_ctr:
2332 Changed |= expandLoadInt(
B,
I, MRI, HII, NewRegs);
2334 case Hexagon::PS_vstorerq_ai:
2335 Changed |= expandStoreVecPred(
B,
I, MRI, HII, NewRegs);
2337 case Hexagon::PS_vloadrq_ai:
2338 Changed |= expandLoadVecPred(
B,
I, MRI, HII, NewRegs);
2340 case Hexagon::PS_vloadrw_ai:
2341 Changed |= expandLoadVec2(
B,
I, MRI, HII, NewRegs);
2343 case Hexagon::PS_vstorerw_ai:
2344 Changed |= expandStoreVec2(
B,
I, MRI, HII, NewRegs);
2358 SavedRegs.
resize(HRI.getNumRegs());
2372 assert(AP.
isValid() &&
"AP must be assigned before register allocation");
2378 expandSpillMacros(MF, NewRegs);
2380 optimizeSpillSlots(MF, NewRegs);
2384 if (!NewRegs.
empty() || mayOverflowFrameOffset(MF)) {
2390 SpillRCs.
insert(&Hexagon::IntRegsRegClass);
2395 for (
const auto *RC : SpillRCs) {
2399 switch (RC->
getID()) {
2400 case Hexagon::IntRegsRegClassID:
2403 case Hexagon::HvxQRRegClassID:
2407 unsigned S = HRI.getSpillSize(*RC);
2408 Align A = HRI.getSpillAlign(*RC);
2409 for (
unsigned i = 0; i < Num; i++) {
2411 RS->addScavengingFrameIndex(NewFI);
2428 auto F = DeadMap.find({Reg,0});
2429 if (
F == DeadMap.end())
2431 for (
auto &DR :
F->second)
2432 if (DR.contains(FIR))
2437 for (
Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2452 SmallVectorImpl<Register> &VRegs)
const {
2454 auto &HII = *HST.getInstrInfo();
2455 auto &HRI = *HST.getRegisterInfo();
2457 HexagonBlockRanges HBR(MF);
2459 using BlockIndexMap =
2460 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2461 using BlockRangeMap =
2462 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2463 using IndexType = HexagonBlockRanges::IndexType;
2470 SlotInfo() =
default;
2473 BlockIndexMap BlockIndexes;
2474 SmallSet<int,4> BadFIs;
2475 std::map<int,SlotInfo> FIRangeMap;
2484 if (HaveRC ==
nullptr || HaveRC == NewRC)
2489 if (NewRC->hasSubClassEq(HaveRC))
2496 for (
auto &
B : MF) {
2497 std::map<int,IndexType> LastStore, LastLoad;
2498 auto P = BlockIndexes.emplace(&
B, HexagonBlockRanges::InstrIndexMap(
B));
2499 auto &IndexMap =
P.first->second;
2501 << IndexMap <<
'\n');
2503 for (
auto &In :
B) {
2507 if (
In.isDebugInstr())
2510 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2511 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2525 int TFI =
Load ? LFI : SFI;
2526 unsigned AM = HII.getAddrMode(In);
2527 SlotInfo &
SI = FIRangeMap[TFI];
2531 unsigned OpNum =
Load ? 0 : 2;
2532 auto *RC = HII.getRegClass(
In.getDesc(), OpNum);
2533 RC = getCommonRC(
SI.RC, RC);
2541 unsigned S = HII.getMemAccessSize(In);
2542 if (
SI.Size != 0 &&
SI.Size != S)
2548 for (
auto *Mo :
In.memoperands()) {
2549 if (!Mo->isVolatile() && !Mo->isAtomic())
2560 for (
unsigned i = 0, n =
In.getNumOperands(); i < n; ++i) {
2561 const MachineOperand &
Op =
In.getOperand(i);
2564 int FI =
Op.getIndex();
2567 if (i+1 >= n || !
In.getOperand(i+1).isImm() ||
2568 In.getOperand(i+1).getImm() != 0)
2570 if (BadFIs.
count(FI))
2574 auto &
LS = LastStore[FI];
2575 auto &LL = LastLoad[FI];
2577 if (LS == IndexType::None)
2578 LS = IndexType::Entry;
2581 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2582 if (LS != IndexType::None)
2583 RL.
add(LS, LL,
false,
false);
2584 else if (LL != IndexType::None)
2585 RL.
add(IndexType::Entry, LL,
false,
false);
2586 LL = IndexType::None;
2594 for (
auto &
I : LastLoad) {
2595 IndexType LL =
I.second;
2596 if (LL == IndexType::None)
2598 auto &RL = FIRangeMap[
I.first].Map[&
B];
2599 IndexType &
LS = LastStore[
I.first];
2600 if (LS != IndexType::None)
2601 RL.
add(LS, LL,
false,
false);
2603 RL.
add(IndexType::Entry, LL,
false,
false);
2604 LS = IndexType::None;
2606 for (
auto &
I : LastStore) {
2607 IndexType
LS =
I.second;
2608 if (LS == IndexType::None)
2610 auto &RL = FIRangeMap[
I.first].Map[&
B];
2611 RL.
add(LS, IndexType::None,
false,
false);
2616 for (
auto &
P : FIRangeMap) {
2617 dbgs() <<
"fi#" <<
P.first;
2618 if (BadFIs.
count(
P.first))
2621 if (
P.second.RC !=
nullptr)
2622 dbgs() << HRI.getRegClassName(
P.second.RC) <<
'\n';
2624 dbgs() <<
"<null>\n";
2625 for (
auto &R :
P.second.Map)
2634 SmallSet<int,4> LoxFIs;
2636 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2638 for (
auto &
P : FIRangeMap) {
2640 if (BadFIs.
count(
P.first))
2642 for (
auto &
B : MF) {
2643 auto F =
P.second.Map.find(&
B);
2645 if (
F ==
P.second.Map.end() ||
F->second.empty())
2647 HexagonBlockRanges::IndexRange &
IR =
F->second.front();
2648 if (
IR.start() == IndexType::Entry)
2649 LoxFIs.insert(
P.first);
2650 BlockFIMap[&
B].push_back(
P.first);
2655 dbgs() <<
"Block-to-FI map (* -- live-on-exit):\n";
2656 for (
auto &
P : BlockFIMap) {
2657 auto &FIs =
P.second;
2661 for (
auto I : FIs) {
2662 dbgs() <<
" fi#" <<
I;
2663 if (LoxFIs.count(
I))
2675 for (
auto &
B : MF) {
2676 auto F = BlockIndexes.find(&
B);
2677 assert(
F != BlockIndexes.end());
2678 HexagonBlockRanges::InstrIndexMap &IM =
F->second;
2682 << HexagonBlockRanges::PrintRangeMap(
DM, HRI));
2684 for (
auto FI : BlockFIMap[&
B]) {
2685 if (BadFIs.
count(FI))
2688 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2689 for (
auto &
Range : RL) {
2691 if (!IndexType::isInstr(
Range.start()) ||
2692 !IndexType::isInstr(
Range.end()))
2696 assert(
SI.mayStore() &&
"Unexpected start instruction");
2698 MachineOperand &SrcOp =
SI.getOperand(2);
2700 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.
getReg(),
2702 auto *RC = HII.getRegClass(
SI.getDesc(), 2);
2719 MachineInstr *CopyIn =
nullptr;
2720 if (SrcRR.
Reg != FoundR || SrcRR.
Sub != 0) {
2722 CopyIn =
BuildMI(
B, StartIt,
DL, HII.get(TargetOpcode::COPY), FoundR)
2728 if (LoxFIs.count(FI) && (&
Range == &RL.back())) {
2731 SrcOp.
setReg(HRI.getSubReg(FoundR, SR));
2743 for (
auto It = StartIt; It != EndIt; It = NextIt) {
2744 MachineInstr &
MI = *It;
2745 NextIt = std::next(It);
2747 if (!HII.isLoadFromStackSlot(
MI, TFI) || TFI != FI)
2750 assert(
MI.getOperand(0).getSubReg() == 0);
2751 MachineInstr *CopyOut =
nullptr;
2752 if (DstR != FoundR) {
2754 unsigned MemSize = HII.getMemAccessSize(
MI);
2756 unsigned CopyOpc = TargetOpcode::COPY;
2757 if (HII.isSignExtendingLoad(
MI))
2758 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2759 else if (HII.isZeroExtendingLoad(
MI))
2760 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2761 CopyOut =
BuildMI(
B, It,
DL, HII.get(CopyOpc), DstR)
2769 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2777void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
MachineFunction &MF,
2778 const HexagonInstrInfo &HII,
2780 MachineBasicBlock &MB = *AI->
getParent();
2790 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2792 if (!NeedsProbing) {
2816 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2820 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), SP)
2858 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2863 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_sub), Rd)
2869 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2878 MF.
insert(InsertPt, LoopMBB);
2880 MF.
insert(InsertPt, ExitMBB);
2891 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2896 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
2902 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
2908 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
2917 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
2921 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_addi), Rd)
2949void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(
MachineInstr *
MI,
2950 const CSIVect &CSI,
bool IsDef,
bool IsKill)
const {
2961 const CSIVect &CSI)
const {
2974 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2977 if (!Hexagon::DoubleRegsRegClass.
contains(R))
2981 int F = Regs.find_first();
2982 if (
F != Hexagon::D8)
2985 int N = Regs.find_next(
F);
2986 if (
N >= 0 &&
N !=
F+1)
2995 const CSIVect &CSI)
const {
2996 if (shouldInlineCSR(MF, CSI))
2998 unsigned NumCSI = CSI.size();
3017 if (HST.getSCSPReg().id() <= MaxReg.id())
3023 return Threshold < NumCSI;
3026bool HexagonFrameLowering::useRestoreFunction(
const MachineFunction &MF,
3027 const CSIVect &CSI)
const {
3028 if (shouldInlineCSR(MF, CSI))
3041 unsigned NumCSI = CSI.size();
3047 return Threshold < NumCSI;
3050bool HexagonFrameLowering::mayOverflowFrameOffset(
MachineFunction &MF)
const {
3055 if (HST.useHVXOps() && StackSize > 256)
3062 bool HasImmStack =
false;
3063 unsigned MinLS = ~0
u;
3065 for (
const MachineBasicBlock &
B : MF) {
3066 for (
const MachineInstr &
MI :
B) {
3068 switch (
MI.getOpcode()) {
3069 case Hexagon::S4_storeirit_io:
3070 case Hexagon::S4_storeirif_io:
3071 case Hexagon::S4_storeiri_io:
3074 case Hexagon::S4_storeirht_io:
3075 case Hexagon::S4_storeirhf_io:
3076 case Hexagon::S4_storeirh_io:
3079 case Hexagon::S4_storeirbt_io:
3080 case Hexagon::S4_storeirbf_io:
3081 case Hexagon::S4_storeirb_io:
3082 if (
MI.getOperand(0).isFI())
3084 MinLS = std::min(MinLS, LS);
3098struct HexagonFrameSortingObject {
3099 bool IsValid =
false;
3105struct HexagonFrameSortingComparator {
3106 inline bool operator()(
const HexagonFrameSortingObject &
A,
3107 const HexagonFrameSortingObject &
B)
const {
3108 return std::make_tuple(!
A.IsValid,
A.ObjectAlignment,
A.Size) <
3109 std::make_tuple(!
B.IsValid,
B.ObjectAlignment,
B.Size);
3119 if (ObjectsToAllocate.
empty())
3123 int NObjects = ObjectsToAllocate.
size();
3131 if (i != ObjectsToAllocate[j])
3142 SortingObjects[i].IsValid =
true;
3143 SortingObjects[i].Index = i;
3153 for (
auto &Obj : SortingObjects) {
3156 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
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.
LLVM_ABI void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction.
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
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
bool isPositionIndependent() const
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
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...
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.
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)
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.