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) {
379 unsigned Opc =
MI.getOpcode();
381 case Hexagon::PS_alloca:
382 case Hexagon::PS_aligna:
405 for (
MCPhysReg S : HRI.subregs_inclusive(R))
410 if (MO.isRegMask()) {
415 const uint32_t *BM = MO.getRegMask();
419 if (!(BM[R/32] & (1u << (R%32))))
434 unsigned RetOpc =
I->getOpcode();
435 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
457 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
458 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
459 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
460 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
461 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
462 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
463 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
464 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
477 return F.hasOptSize() && !
F.hasMinSize();
488void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
489 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB)
const {
490 static unsigned ShrinkCounter = 0;
492 if (MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
501 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
503 MachineDominatorTree MDT;
505 MachinePostDominatorTree MPT;
508 using UnsignedMap = DenseMap<unsigned, unsigned>;
509 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
515 RPO[
I->getNumber()] = RPON++;
521 unsigned BN = RPO[
I.getNumber()];
522 for (MachineBasicBlock *Succ :
I.successors())
524 if (RPO[Succ->getNumber()] <= BN)
531 BitVector CSR(Hexagon::NUM_TARGET_REGS);
532 for (
const MCPhysReg *
P = HRI.getCalleeSavedRegs(&MF); *
P; ++
P)
541 dbgs() <<
"Blocks needing SF: {";
542 for (
auto &
B : SFBlocks)
547 if (SFBlocks.
empty())
551 MachineBasicBlock *DomB = SFBlocks[0];
552 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
557 MachineBasicBlock *PDomB = SFBlocks[0];
558 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
564 dbgs() <<
"Computed dom block: ";
569 dbgs() <<
", computed pdom block: ";
585 LLVM_DEBUG(
dbgs() <<
"PDom block does not post-dominate dom block\n");
608 findShrunkPrologEpilog(MF, PrologB, EpilogB);
610 bool PrologueStubs =
false;
611 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
612 insertPrologueInBlock(*PrologB, PrologueStubs);
620 while (AfterProlog != PrologB->
end() &&
626 updateEntryPaths(MF, *PrologB);
629 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
630 insertEpilogueInBlock(*EpilogB);
633 if (
B.isReturnBlock())
634 insertCSRRestoresInBlock(
B, CSI, HRI);
637 if (
B.isReturnBlock())
638 insertEpilogueInBlock(
B);
656 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
657 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
666 assert(
F.hasFnAttribute(Attribute::NoReturn) &&
667 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
668 !
F.getFunction().hasFnAttribute(Attribute::UWTable));
684 assert(!MFI.hasVarSizedObjects() &&
685 !HST.getRegisterInfo()->hasStackRealignment(MF));
686 return F.hasFnAttribute(Attribute::NoReturn) &&
687 F.hasFnAttribute(Attribute::NoUnwind) &&
688 !
F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
689 MFI.getStackSize() == 0;
692void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &
MBB,
693 bool PrologueStubs)
const {
709 FrameSize = MaxCFA +
alignTo(FrameSize, MaxAlign);
720 SmallVector<MachineInstr *, 4> AdjustRegs;
723 if (
MI.getOpcode() == Hexagon::PS_alloca)
726 for (
auto *
MI : AdjustRegs) {
727 assert((
MI->getOpcode() == Hexagon::PS_alloca) &&
"Expected alloca");
728 expandAlloca(
MI, MF, HII, SP, MaxCF);
729 MI->eraseFromParent();
734 if (MF.getFunction().isVarArg() &&
735 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
737 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
738 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
740 : NumVarArgRegs * 4 + 4;
741 if (RegisterSavedAreaSizePlusPadding > 0) {
744 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
746 .
addImm(-RegisterSavedAreaSizePlusPadding)
751 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
752 for (
int i = HMFI.getFirstNamedArgFrameIndex(),
753 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
758 unsigned LDOpc, STOpc;
759 uint64_t OpcodeChecker = ObjAlign.
value();
762 if (ObjAlign > ObjSize) {
765 else if (ObjSize <= 2)
767 else if (ObjSize <= 4)
769 else if (ObjSize > 4)
773 switch (OpcodeChecker) {
775 LDOpc = Hexagon::L2_loadrb_io;
776 STOpc = Hexagon::S2_storerb_io;
779 LDOpc = Hexagon::L2_loadrh_io;
780 STOpc = Hexagon::S2_storerh_io;
783 LDOpc = Hexagon::L2_loadri_io;
784 STOpc = Hexagon::S2_storeri_io;
788 LDOpc = Hexagon::L2_loadrd_io;
789 STOpc = Hexagon::S2_storerd_io;
793 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
795 int LoadStoreCount = ObjSize / OpcodeChecker;
797 if (ObjSize % OpcodeChecker)
805 NumBytes =
alignTo(NumBytes, ObjAlign);
808 while (
Count < LoadStoreCount) {
810 BuildMI(
MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
812 .
addImm(RegisterSavedAreaSizePlusPadding +
829 NumBytes =
alignTo(NumBytes, 8);
834 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
836 for (
int j = FirstVarArgSavedReg, i = 0;
j < 6; ++
j, ++i) {
837 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
847 insertAllocframe(
MBB, InsertPt, NumBytes);
849 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
857 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
859 }
else if (NumBytes > 0) {
861 auto *TLI = HST.getTargetLowering();
862 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
863 unsigned ProbeSize = 0;
866 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
868 if (NeedsProbing && NumBytes > ProbeSize) {
870 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
875 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
879 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
887void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &
MBB)
const {
901 MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
903 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
904 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
905 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
906 NumBytes += RegisterSavedAreaSizePlusPadding;
909 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
917 unsigned RetOpc = RetI ? RetI->
getOpcode() : 0;
920 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
923 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
926 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
937 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
938 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
939 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
940 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
957 bool NeedsDeallocframe =
true;
958 unsigned PrevOpc = 0;
961 PrevOpc = PrevIt->getOpcode();
962 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
963 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
964 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
965 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
966 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
967 NeedsDeallocframe =
false;
970 if (!MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
972 if (!NeedsDeallocframe) {
977 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
978 PrevOpc != Hexagon::PS_callr_nr)
980 "useRestoreFunction() should have prevented this");
987 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
996 unsigned NewOpc = Hexagon::L4_return;
997 MachineInstr *NewI =
BuildMI(
MBB, RetI, dl, HII.get(NewOpc))
1006 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
1007 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
1008 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
1013 bool HasRestoreStub =
1015 (
I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1017 Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1018 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1019 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC);
1020 if (!HasRestoreStub)
1021 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1024 if (RegisterSavedAreaSizePlusPadding != 0)
1025 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1027 .
addImm(RegisterSavedAreaSizePlusPadding);
1031 if (NeedsSCS && !HasRestoreStub)
1036void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &
MBB,
1045 const unsigned int ALLOCFRAME_MAX = 16384;
1055 auto *TLI = HST.getTargetLowering();
1056 bool NeedsProbing = TLI->hasInlineStackProbe(MF) && NumBytes > 0;
1057 unsigned ProbeSize = 0;
1060 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1063 if (NeedsProbing && NumBytes > ProbeSize) {
1065 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1073 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
1079 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
1082 }
else if (NumBytes >= ALLOCFRAME_MAX) {
1084 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1093 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1098 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1113 if (
MI.getOpcode() == Hexagon::PS_probed_stackalloc)
1118 auto *TLI = HST.getTargetLowering();
1120 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1126 Register TargetReg =
MI->getOperand(0).getReg();
1133 MF.
insert(InsertPt, LoopMBB);
1136 MF.
insert(InsertPt, ExitMBB);
1157 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi),
1163 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
1169 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
1175 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
1181 BuildMI(*ExitMBB, ExitMBB->
begin(),
DL, HII.get(Hexagon::A2_tfr),
1187 MBB->addSuccessor(LoopMBB);
1192 MI->eraseFromParent();
1209 for (
unsigned i = 0; i < Worklist.
size(); ++i) {
1210 unsigned BN = Worklist[i];
1213 if (!
MBB.isLiveIn(R.getReg()))
1214 MBB.addLiveIn(R.getReg());
1216 for (
auto &SB :
MBB.successors())
1217 Worklist.
insert(SB->getNumber());
1221bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &
MBB,
1222 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
1223 BitVector &Path)
const {
1226 if (Path[BN] || DoneF[BN])
1234 bool ReachedExit =
false;
1236 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
1242 MachineInstr &RetI =
MBB.
back();
1252 if (ReachedExit && &
MBB != &RestoreB) {
1265static std::optional<MachineBasicBlock::iterator>
1272 auto End =
B.instr_end();
1276 if (!
I.isBundle()) {
1277 if (
I.getOpcode() == Hexagon::S2_allocframe)
1278 return std::next(It);
1282 bool HasCall =
false, HasAllocFrame =
false;
1284 while (++
T != End &&
T->isBundled()) {
1285 if (
T->getOpcode() == Hexagon::S2_allocframe)
1286 HasAllocFrame =
true;
1287 else if (
T->isCall())
1291 return HasCall ? It : std::next(It);
1293 return std::nullopt;
1299 insertCFIInstructionsAt(
B, *At);
1314 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1317 bool HasFP = hasFP(MF);
1320 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(),
true);
1321 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(),
true);
1348 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1349 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1350 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1351 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1352 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1353 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1359 auto IfR = [
Reg] (
const CalleeSavedInfo &
C) ->
bool {
1360 return C.getReg() ==
Reg;
1379 getFrameIndexReference(MF,
F->getFrameIdx(), FrameReg).getFixed();
1385 unsigned DwarfReg = HRI.getDwarfRegNum(
Reg,
true);
1397 Register HiReg = HRI.getSubReg(
Reg, Hexagon::isub_hi);
1398 Register LoReg = HRI.getSubReg(
Reg, Hexagon::isub_lo);
1399 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg,
true);
1400 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg,
true);
1416 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1432 if (HasAlloca || HasExtraAlign)
1462 bool Stkchk =
false) {
1463 const char * V4SpillToMemoryFunctions[] = {
1464 "__save_r16_through_r17",
1465 "__save_r16_through_r19",
1466 "__save_r16_through_r21",
1467 "__save_r16_through_r23",
1468 "__save_r16_through_r25",
1469 "__save_r16_through_r27" };
1471 const char * V4SpillToMemoryStkchkFunctions[] = {
1472 "__save_r16_through_r17_stkchk",
1473 "__save_r16_through_r19_stkchk",
1474 "__save_r16_through_r21_stkchk",
1475 "__save_r16_through_r23_stkchk",
1476 "__save_r16_through_r25_stkchk",
1477 "__save_r16_through_r27_stkchk" };
1479 const char * V4SpillFromMemoryFunctions[] = {
1480 "__restore_r16_through_r17_and_deallocframe",
1481 "__restore_r16_through_r19_and_deallocframe",
1482 "__restore_r16_through_r21_and_deallocframe",
1483 "__restore_r16_through_r23_and_deallocframe",
1484 "__restore_r16_through_r25_and_deallocframe",
1485 "__restore_r16_through_r27_and_deallocframe" };
1487 const char * V4SpillFromMemoryTailcallFunctions[] = {
1488 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1489 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1490 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1491 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1492 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1493 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1496 const char **SpillFunc =
nullptr;
1500 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1501 : V4SpillToMemoryFunctions;
1504 SpillFunc = V4SpillFromMemoryFunctions;
1507 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1510 assert(SpillFunc &&
"Unknown spill kind");
1515 return SpillFunc[0];
1517 return SpillFunc[1];
1519 return SpillFunc[2];
1521 return SpillFunc[3];
1523 return SpillFunc[4];
1525 return SpillFunc[5];
1540 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1545 Register SP = HRI.getStackRegister();
1547 Register AP = HMFI.getStackAlignBaseReg();
1562 bool UseFP =
false, UseAP =
false;
1567 if (NoOpt && !HasExtraAlign)
1572 UseFP |= (HasAlloca || HasExtraAlign);
1583 bool HasFP =
hasFP(MF);
1584 assert((HasFP || !UseFP) &&
"This function must have frame pointer");
1610 if (
Offset > 0 && !HasFP)
1625 if (!UseFP && !UseAP)
1626 RealOffset = FrameSize+
Offset;
1632 bool &PrologueStubs)
const {
1637 PrologueStubs =
false;
1642 if (useSpillFunction(MF, CSI)) {
1643 PrologueStubs =
true;
1655 if (StkOvrFlowEnabled) {
1657 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1658 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1660 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1661 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1664 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1665 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1667 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1668 : Hexagon::SAVE_REGISTERS_CALL_V4;
1671 MachineInstr *SaveRegsCall =
1676 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI,
false,
true);
1678 for (
const CalleeSavedInfo &
I : CSI)
1681 for (
const CalleeSavedInfo &
I : CSI) {
1682 MCRegister
Reg =
I.getReg();
1687 int FI =
I.getFrameIdx();
1701 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
1702 if (
const MachineInstr *AlignaI = HFI.getAlignaInstr(MF)) {
1703 MachineInstr *AI =
const_cast<MachineInstr *
>(AlignaI);
1716bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &
MBB,
1717 const CSIVect &CSI,
const HexagonRegisterInfo &HRI)
const {
1726 if (useRestoreFunction(MF, CSI)) {
1731 auto &HTM =
static_cast<const HexagonTargetMachine&
>(MF.
getTarget());
1732 bool IsPIC = HTM.isPositionIndependent();
1738 MachineInstr *DeallocCall =
nullptr;
1743 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1744 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1746 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1747 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1756 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1757 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1759 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1760 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1766 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI,
true,
false);
1770 for (
const CalleeSavedInfo &
I : CSI) {
1771 MCRegister
Reg =
I.getReg();
1773 int FI =
I.getFrameIdx();
1784 unsigned Opc =
MI.getOpcode();
1786 assert((
Opc == Hexagon::ADJCALLSTACKDOWN ||
Opc == Hexagon::ADJCALLSTACKUP) &&
1787 "Cannot handle this call frame pseudo instruction");
1788 return MBB.erase(
I);
1801 if (!HasAlloca || !NeedsAlign)
1807 AP = AI->getOperand(0).getReg();
1810 HMFI.setStackAlignBaseReg(AP);
1818 auto IsUsed = [&HRI,&MRI] (
Register Reg) ->
bool {
1850 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1880 bool HasResSub =
false;
1906 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1912 for (
int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1950 int64_t MinOffset = 0;
1952 for (
const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1957 MinOffset = std::min(MinOffset, S->Offset);
1959 SRegs[S->Reg] =
false;
1968 unsigned Size =
TRI->getSpillSize(*RC);
1969 int64_t Off = MinOffset -
Size;
1971 Off &= -Alignment.
value();
1973 MinOffset = std::min(MinOffset, Off);
1979 dbgs() <<
"CS information: {";
1981 int FI =
I.getFrameIdx();
1993 bool MissedReg =
false;
2013 if (!Hexagon::ModRegsRegClass.
contains(DstR) ||
2014 !Hexagon::ModRegsRegClass.
contains(SrcR))
2018 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), TmpR).
add(
MI->getOperand(1));
2019 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), DstR)
2031 if (!
MI->getOperand(0).isFI())
2035 unsigned Opc =
MI->getOpcode();
2037 bool IsKill =
MI->getOperand(2).isKill();
2038 int FI =
MI->getOperand(0).getIndex();
2043 unsigned TfrOpc = (
Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2049 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2060bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &
B,
2062 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2063 MachineInstr *
MI = &*It;
2064 if (!
MI->getOperand(1).isFI())
2068 unsigned Opc =
MI->getOpcode();
2070 int FI =
MI->getOperand(1).getIndex();
2074 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2081 unsigned TfrOpc = (
Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2082 : Hexagon::A2_tfrrcr;
2084 .
addReg(TmpR, RegState::Kill);
2091bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &
B,
2093 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2094 MachineInstr *
MI = &*It;
2095 if (!
MI->getOperand(0).isFI())
2100 bool IsKill =
MI->getOperand(2).isKill();
2101 int FI =
MI->getOperand(0).getIndex();
2102 auto *RC = &Hexagon::HvxVRRegClass;
2111 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2114 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2116 .
addReg(TmpR0, RegState::Kill);
2119 expandStoreVec(
B, std::prev(It), MRI, HII, NewRegs);
2127bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &
B,
2129 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2130 MachineInstr *
MI = &*It;
2131 if (!
MI->getOperand(1).isFI())
2136 int FI =
MI->getOperand(1).getIndex();
2137 auto *RC = &Hexagon::HvxVRRegClass;
2145 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2148 expandLoadVec(
B, std::prev(It), MRI, HII, NewRegs);
2150 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandvrt), DstR)
2151 .
addReg(TmpR1, RegState::Kill)
2152 .
addReg(TmpR0, RegState::Kill);
2160bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &
B,
2162 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2163 MachineFunction &MF = *
B.getParent();
2165 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2166 MachineInstr *
MI = &*It;
2167 if (!
MI->getOperand(0).isFI())
2174 LivePhysRegs LPR(HRI);
2177 for (
auto R =
B.begin(); R != It; ++R) {
2179 LPR.stepForward(*R, Clobbers);
2184 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2185 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2186 bool IsKill =
MI->getOperand(2).isKill();
2187 int FI =
MI->getOperand(0).getIndex();
2189 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2190 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2195 if (LPR.contains(SrcLo)) {
2196 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2197 : Hexagon::V6_vS32Ub_ai;
2206 if (LPR.contains(SrcHi)) {
2207 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2208 : Hexagon::V6_vS32Ub_ai;
2220bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &
B,
2222 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2223 MachineFunction &MF = *
B.getParent();
2225 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2226 MachineInstr *
MI = &*It;
2227 if (!
MI->getOperand(1).isFI())
2232 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2233 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2234 int FI =
MI->getOperand(1).getIndex();
2236 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2237 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2242 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2243 : Hexagon::V6_vL32Ub_ai;
2250 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2251 : Hexagon::V6_vL32Ub_ai;
2261bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &
B,
2263 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2264 MachineFunction &MF = *
B.getParent();
2266 MachineInstr *
MI = &*It;
2267 if (!
MI->getOperand(0).isFI())
2270 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2273 bool IsKill =
MI->getOperand(2).isKill();
2274 int FI =
MI->getOperand(0).getIndex();
2276 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2278 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2279 : Hexagon::V6_vS32Ub_ai;
2290bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &
B,
2292 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2293 MachineFunction &MF = *
B.getParent();
2295 MachineInstr *
MI = &*It;
2296 if (!
MI->getOperand(1).isFI())
2299 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2302 int FI =
MI->getOperand(1).getIndex();
2304 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2306 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2307 : Hexagon::V6_vL32Ub_ai;
2317bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
2318 SmallVectorImpl<Register> &NewRegs)
const {
2319 auto &HII = *MF.
getSubtarget<HexagonSubtarget>().getInstrInfo();
2323 for (
auto &
B : MF) {
2326 for (
auto I =
B.begin(),
E =
B.end();
I !=
E;
I = NextI) {
2327 MachineInstr *
MI = &*
I;
2328 NextI = std::next(
I);
2329 unsigned Opc =
MI->getOpcode();
2332 case TargetOpcode::COPY:
2333 Changed |= expandCopy(
B,
I, MRI, HII, NewRegs);
2335 case Hexagon::STriw_pred:
2336 case Hexagon::STriw_ctr:
2337 Changed |= expandStoreInt(
B,
I, MRI, HII, NewRegs);
2339 case Hexagon::LDriw_pred:
2340 case Hexagon::LDriw_ctr:
2341 Changed |= expandLoadInt(
B,
I, MRI, HII, NewRegs);
2343 case Hexagon::PS_vstorerq_ai:
2344 Changed |= expandStoreVecPred(
B,
I, MRI, HII, NewRegs);
2346 case Hexagon::PS_vloadrq_ai:
2347 Changed |= expandLoadVecPred(
B,
I, MRI, HII, NewRegs);
2349 case Hexagon::PS_vloadrw_ai:
2350 Changed |= expandLoadVec2(
B,
I, MRI, HII, NewRegs);
2352 case Hexagon::PS_vstorerw_ai:
2353 Changed |= expandStoreVec2(
B,
I, MRI, HII, NewRegs);
2367 SavedRegs.
resize(HRI.getNumRegs());
2377 expandSpillMacros(MF, NewRegs);
2379 optimizeSpillSlots(MF, NewRegs);
2383 if (!NewRegs.
empty() || mayOverflowFrameOffset(MF)) {
2389 SpillRCs.
insert(&Hexagon::IntRegsRegClass);
2394 for (
const auto *RC : SpillRCs) {
2398 switch (RC->
getID()) {
2399 case Hexagon::IntRegsRegClassID:
2402 case Hexagon::HvxQRRegClassID:
2406 unsigned S = HRI.getSpillSize(*RC);
2407 Align A = HRI.getSpillAlign(*RC);
2408 for (
unsigned i = 0; i < Num; i++) {
2410 RS->addScavengingFrameIndex(NewFI);
2427 auto F = DeadMap.find({Reg,0});
2428 if (
F == DeadMap.end())
2430 for (
auto &DR :
F->second)
2431 if (DR.contains(FIR))
2436 for (
Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2450void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
2451 SmallVectorImpl<Register> &VRegs)
const {
2453 auto &HII = *HST.getInstrInfo();
2454 auto &HRI = *HST.getRegisterInfo();
2456 HexagonBlockRanges HBR(MF);
2458 using BlockIndexMap =
2459 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2460 using BlockRangeMap =
2461 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2462 using IndexType = HexagonBlockRanges::IndexType;
2469 SlotInfo() =
default;
2472 BlockIndexMap BlockIndexes;
2473 SmallSet<int,4> BadFIs;
2474 std::map<int,SlotInfo> FIRangeMap;
2483 if (HaveRC ==
nullptr || HaveRC == NewRC)
2488 if (NewRC->hasSubClassEq(HaveRC))
2495 for (
auto &
B : MF) {
2496 std::map<int,IndexType> LastStore, LastLoad;
2497 auto P = BlockIndexes.emplace(&
B, HexagonBlockRanges::InstrIndexMap(
B));
2498 auto &IndexMap =
P.first->second;
2500 << IndexMap <<
'\n');
2502 for (
auto &In :
B) {
2506 if (
In.isDebugInstr())
2509 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2510 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2524 int TFI =
Load ? LFI : SFI;
2525 unsigned AM = HII.getAddrMode(In);
2526 SlotInfo &
SI = FIRangeMap[TFI];
2530 unsigned OpNum =
Load ? 0 : 2;
2531 auto *RC = HII.getRegClass(
In.getDesc(), OpNum);
2532 RC = getCommonRC(
SI.RC, RC);
2540 unsigned S = HII.getMemAccessSize(In);
2541 if (
SI.Size != 0 &&
SI.Size != S)
2547 for (
auto *Mo :
In.memoperands()) {
2548 if (!Mo->isVolatile() && !Mo->isAtomic())
2559 for (
unsigned i = 0, n =
In.getNumOperands(); i < n; ++i) {
2560 const MachineOperand &
Op =
In.getOperand(i);
2563 int FI =
Op.getIndex();
2566 if (i+1 >= n || !
In.getOperand(i+1).isImm() ||
2567 In.getOperand(i+1).getImm() != 0)
2569 if (BadFIs.
count(FI))
2573 auto &
LS = LastStore[FI];
2574 auto &LL = LastLoad[FI];
2576 if (LS == IndexType::None)
2577 LS = IndexType::Entry;
2580 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2581 if (LS != IndexType::None)
2582 RL.
add(LS, LL,
false,
false);
2583 else if (LL != IndexType::None)
2584 RL.
add(IndexType::Entry, LL,
false,
false);
2585 LL = IndexType::None;
2593 for (
auto &
I : LastLoad) {
2594 IndexType LL =
I.second;
2595 if (LL == IndexType::None)
2597 auto &RL = FIRangeMap[
I.first].Map[&
B];
2598 IndexType &
LS = LastStore[
I.first];
2599 if (LS != IndexType::None)
2600 RL.
add(LS, LL,
false,
false);
2602 RL.
add(IndexType::Entry, LL,
false,
false);
2603 LS = IndexType::None;
2605 for (
auto &
I : LastStore) {
2606 IndexType
LS =
I.second;
2607 if (LS == IndexType::None)
2609 auto &RL = FIRangeMap[
I.first].Map[&
B];
2610 RL.
add(LS, IndexType::None,
false,
false);
2615 for (
auto &
P : FIRangeMap) {
2616 dbgs() <<
"fi#" <<
P.first;
2617 if (BadFIs.
count(
P.first))
2620 if (
P.second.RC !=
nullptr)
2621 dbgs() << HRI.getRegClassName(
P.second.RC) <<
'\n';
2623 dbgs() <<
"<null>\n";
2624 for (
auto &R :
P.second.Map)
2633 SmallSet<int,4> LoxFIs;
2635 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2637 for (
auto &
P : FIRangeMap) {
2639 if (BadFIs.
count(
P.first))
2641 for (
auto &
B : MF) {
2642 auto F =
P.second.Map.find(&
B);
2644 if (
F ==
P.second.Map.end() ||
F->second.empty())
2646 HexagonBlockRanges::IndexRange &
IR =
F->second.front();
2647 if (
IR.start() == IndexType::Entry)
2648 LoxFIs.insert(
P.first);
2649 BlockFIMap[&
B].push_back(
P.first);
2654 dbgs() <<
"Block-to-FI map (* -- live-on-exit):\n";
2655 for (
auto &
P : BlockFIMap) {
2656 auto &FIs =
P.second;
2660 for (
auto I : FIs) {
2661 dbgs() <<
" fi#" <<
I;
2662 if (LoxFIs.count(
I))
2674 for (
auto &
B : MF) {
2675 auto F = BlockIndexes.find(&
B);
2676 assert(
F != BlockIndexes.end());
2677 HexagonBlockRanges::InstrIndexMap &IM =
F->second;
2681 << HexagonBlockRanges::PrintRangeMap(
DM, HRI));
2683 for (
auto FI : BlockFIMap[&
B]) {
2684 if (BadFIs.
count(FI))
2687 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2688 for (
auto &
Range : RL) {
2690 if (!IndexType::isInstr(
Range.start()) ||
2691 !IndexType::isInstr(
Range.end()))
2695 assert(
SI.mayStore() &&
"Unexpected start instruction");
2697 MachineOperand &SrcOp =
SI.getOperand(2);
2699 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.
getReg(),
2701 auto *RC = HII.getRegClass(
SI.getDesc(), 2);
2718 MachineInstr *CopyIn =
nullptr;
2719 if (SrcRR.
Reg != FoundR || SrcRR.
Sub != 0) {
2721 CopyIn =
BuildMI(
B, StartIt,
DL, HII.get(TargetOpcode::COPY), FoundR)
2727 if (LoxFIs.count(FI) && (&
Range == &RL.back())) {
2730 SrcOp.
setReg(HRI.getSubReg(FoundR, SR));
2742 for (
auto It = StartIt; It != EndIt; It = NextIt) {
2743 MachineInstr &
MI = *It;
2744 NextIt = std::next(It);
2746 if (!HII.isLoadFromStackSlot(
MI, TFI) || TFI != FI)
2749 assert(
MI.getOperand(0).getSubReg() == 0);
2750 MachineInstr *CopyOut =
nullptr;
2751 if (DstR != FoundR) {
2753 unsigned MemSize = HII.getMemAccessSize(
MI);
2755 unsigned CopyOpc = TargetOpcode::COPY;
2756 if (HII.isSignExtendingLoad(
MI))
2757 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2758 else if (HII.isZeroExtendingLoad(
MI))
2759 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2760 CopyOut =
BuildMI(
B, It,
DL, HII.get(CopyOpc), DstR)
2768 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2776void HexagonFrameLowering::expandAlloca(MachineInstr *AI, MachineFunction &MF,
2777 const HexagonInstrInfo &HII,
2779 MachineBasicBlock &MB = *AI->
getParent();
2789 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2791 if (!NeedsProbing) {
2815 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2819 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), SP)
2857 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2862 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_sub), Rd)
2868 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2877 MF.
insert(InsertPt, LoopMBB);
2879 MF.
insert(InsertPt, ExitMBB);
2890 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2895 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
2901 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
2907 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
2916 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
2920 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_addi), Rd)
2950 if (
I.getOpcode() == Hexagon::PS_aligna)
2957void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(
MachineInstr *
MI,
2958 const CSIVect &CSI,
bool IsDef,
bool IsKill)
const {
2969 const CSIVect &CSI)
const {
2982 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2985 if (!Hexagon::DoubleRegsRegClass.
contains(R))
2989 int F = Regs.find_first();
2990 if (
F != Hexagon::D8)
2993 int N = Regs.find_next(
F);
2994 if (
N >= 0 &&
N !=
F+1)
3002bool HexagonFrameLowering::useSpillFunction(
const MachineFunction &MF,
3003 const CSIVect &CSI)
const {
3004 if (shouldInlineCSR(MF, CSI))
3006 unsigned NumCSI = CSI.size();
3025 if (HST.getSCSPReg().id() <= MaxReg.id())
3031 return Threshold < NumCSI;
3034bool HexagonFrameLowering::useRestoreFunction(
const MachineFunction &MF,
3035 const CSIVect &CSI)
const {
3036 if (shouldInlineCSR(MF, CSI))
3049 unsigned NumCSI = CSI.size();
3055 return Threshold < NumCSI;
3058bool HexagonFrameLowering::mayOverflowFrameOffset(MachineFunction &MF)
const {
3063 if (HST.useHVXOps() && StackSize > 256)
3070 bool HasImmStack =
false;
3071 unsigned MinLS = ~0
u;
3073 for (
const MachineBasicBlock &
B : MF) {
3074 for (
const MachineInstr &
MI :
B) {
3076 switch (
MI.getOpcode()) {
3077 case Hexagon::S4_storeirit_io:
3078 case Hexagon::S4_storeirif_io:
3079 case Hexagon::S4_storeiri_io:
3082 case Hexagon::S4_storeirht_io:
3083 case Hexagon::S4_storeirhf_io:
3084 case Hexagon::S4_storeirh_io:
3087 case Hexagon::S4_storeirbt_io:
3088 case Hexagon::S4_storeirbf_io:
3089 case Hexagon::S4_storeirb_io:
3090 if (
MI.getOperand(0).isFI())
3092 MinLS = std::min(MinLS, LS);
3106struct HexagonFrameSortingObject {
3107 bool IsValid =
false;
3113struct HexagonFrameSortingComparator {
3114 inline bool operator()(
const HexagonFrameSortingObject &
A,
3115 const HexagonFrameSortingObject &
B)
const {
3116 return std::make_tuple(!
A.IsValid,
A.ObjectAlignment,
A.Size) <
3117 std::make_tuple(!
B.IsValid,
B.ObjectAlignment,
B.Size);
3127 if (ObjectsToAllocate.
empty())
3131 int NObjects = ObjectsToAllocate.
size();
3139 if (i != ObjectsToAllocate[j])
3150 SortingObjects[i].IsValid =
true;
3151 SortingObjects[i].Index = i;
3161 for (
auto &Obj : SortingObjects) {
3164 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)
const MachineInstr * getAlignaInstr(const MachineFunction &MF) const
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 processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
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.
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.
constexpr bool isValid() const
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
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 the alignment in bytes that this function must be aligned to, which is greater than the defaul...
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.