68#define DEBUG_TYPE "hexagon-pei"
163 if (!HST.getFrameLowering()->hasFP(MF))
170 const auto &HII = *HST.getInstrInfo();
184 MBB.addLiveIn(SCSPReg);
192 unsigned DwarfSCSReg =
TRI.getDwarfRegNum(SCSPReg,
true);
195 assert(DwarfSCSReg < 32 &&
"SCS register should be < 32");
196 const char CFIInst[] = {
197 (
char)dwarf::DW_CFA_val_expression,
200 (
char)(
unsigned)(dwarf::DW_OP_breg0 + DwarfSCSReg),
223 BuildMI(
MBB,
MI,
DL, HII.get(Hexagon::L2_loadri_io), Hexagon::R31)
242 cl::desc(
"Set the number of scavenger slots"),
247 cl::desc(
"Specify O2(not Os) spill func threshold"),
252 cl::desc(
"Specify Os spill func threshold"),
261 cl::desc(
"Enable stack frame shrink wrapping"));
266 cl::desc(
"Max count of stack frame shrink-wraps"));
270 cl::desc(
"Enable long calls for save-restore stubs."),
281 cl::init(std::numeric_limits<unsigned>::max()));
300 char HexagonCallFrameInformation::ID = 0;
304bool HexagonCallFrameInformation::runOnMachineFunction(
MachineFunction &MF) {
305 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
310 HFI.insertCFIInstructions(MF);
315 "Hexagon call frame information",
false,
false)
318 return new HexagonCallFrameInformation();
335 if (!RegNo || SubReg < RegNo)
345 static_assert(Hexagon::R1 > 0,
346 "Assume physical registers are encoded as positive integers");
351 for (
unsigned I = 1,
E = CSI.
size();
I <
E; ++
I) {
366 unsigned Opc =
MI.getOpcode();
368 case Hexagon::PS_alloca:
369 case Hexagon::PS_aligna:
392 for (
MCPhysReg S : HRI.subregs_inclusive(R))
397 if (MO.isRegMask()) {
402 const uint32_t *BM = MO.getRegMask();
406 if (!(BM[R/32] & (1u << (R%32))))
421 unsigned RetOpc =
I->getOpcode();
422 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
444 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
445 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
446 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
447 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
448 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
449 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
450 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
451 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
464 return F.hasOptSize() && !
F.hasMinSize();
475void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
476 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB)
const {
477 static unsigned ShrinkCounter = 0;
479 if (MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
488 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
490 MachineDominatorTree MDT;
492 MachinePostDominatorTree MPT;
495 using UnsignedMap = DenseMap<unsigned, unsigned>;
496 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
502 RPO[
I->getNumber()] = RPON++;
508 unsigned BN = RPO[
I.getNumber()];
509 for (MachineBasicBlock *Succ :
I.successors())
511 if (RPO[Succ->getNumber()] <= BN)
518 BitVector CSR(Hexagon::NUM_TARGET_REGS);
519 for (
const MCPhysReg *
P = HRI.getCalleeSavedRegs(&MF); *
P; ++
P)
528 dbgs() <<
"Blocks needing SF: {";
529 for (
auto &
B : SFBlocks)
534 if (SFBlocks.
empty())
538 MachineBasicBlock *DomB = SFBlocks[0];
539 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
544 MachineBasicBlock *PDomB = SFBlocks[0];
545 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
551 dbgs() <<
"Computed dom block: ";
556 dbgs() <<
", computed pdom block: ";
572 LLVM_DEBUG(
dbgs() <<
"PDom block does not post-dominate dom block\n");
595 findShrunkPrologEpilog(MF, PrologB, EpilogB);
597 bool PrologueStubs =
false;
598 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
599 insertPrologueInBlock(*PrologB, PrologueStubs);
607 while (AfterProlog != PrologB->
end() &&
613 updateEntryPaths(MF, *PrologB);
616 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
617 insertEpilogueInBlock(*EpilogB);
620 if (
B.isReturnBlock())
621 insertCSRRestoresInBlock(
B, CSI, HRI);
624 if (
B.isReturnBlock())
625 insertEpilogueInBlock(
B);
643 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
644 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
653 assert(
F.hasFnAttribute(Attribute::NoReturn) &&
654 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
655 !
F.getFunction().hasFnAttribute(Attribute::UWTable));
671 assert(!MFI.hasVarSizedObjects() &&
672 !HST.getRegisterInfo()->hasStackRealignment(MF));
673 return F.hasFnAttribute(Attribute::NoReturn) &&
674 F.hasFnAttribute(Attribute::NoUnwind) &&
675 !
F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
676 MFI.getStackSize() == 0;
679void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &
MBB,
680 bool PrologueStubs)
const {
696 FrameSize = MaxCFA +
alignTo(FrameSize, MaxAlign);
707 SmallVector<MachineInstr *, 4> AdjustRegs;
710 if (
MI.getOpcode() == Hexagon::PS_alloca)
713 for (
auto *
MI : AdjustRegs) {
714 assert((
MI->getOpcode() == Hexagon::PS_alloca) &&
"Expected alloca");
715 expandAlloca(
MI, MF, HII, SP, MaxCF);
716 MI->eraseFromParent();
721 if (MF.getFunction().isVarArg() &&
722 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
724 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
725 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
727 : NumVarArgRegs * 4 + 4;
728 if (RegisterSavedAreaSizePlusPadding > 0) {
731 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
733 .
addImm(-RegisterSavedAreaSizePlusPadding)
738 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
739 for (
int i = HMFI.getFirstNamedArgFrameIndex(),
740 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
745 unsigned LDOpc, STOpc;
746 uint64_t OpcodeChecker = ObjAlign.
value();
749 if (ObjAlign > ObjSize) {
752 else if (ObjSize <= 2)
754 else if (ObjSize <= 4)
756 else if (ObjSize > 4)
760 switch (OpcodeChecker) {
762 LDOpc = Hexagon::L2_loadrb_io;
763 STOpc = Hexagon::S2_storerb_io;
766 LDOpc = Hexagon::L2_loadrh_io;
767 STOpc = Hexagon::S2_storerh_io;
770 LDOpc = Hexagon::L2_loadri_io;
771 STOpc = Hexagon::S2_storeri_io;
775 LDOpc = Hexagon::L2_loadrd_io;
776 STOpc = Hexagon::S2_storerd_io;
780 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
782 int LoadStoreCount = ObjSize / OpcodeChecker;
784 if (ObjSize % OpcodeChecker)
792 NumBytes =
alignTo(NumBytes, ObjAlign);
795 while (
Count < LoadStoreCount) {
797 BuildMI(
MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
799 .
addImm(RegisterSavedAreaSizePlusPadding +
816 NumBytes =
alignTo(NumBytes, 8);
821 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
823 for (
int j = FirstVarArgSavedReg, i = 0;
j < 6; ++
j, ++i) {
824 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
834 insertAllocframe(
MBB, InsertPt, NumBytes);
836 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
844 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
846 }
else if (NumBytes > 0) {
848 auto *TLI = HST.getTargetLowering();
849 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
850 unsigned ProbeSize = 0;
853 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
855 if (NeedsProbing && NumBytes > ProbeSize) {
857 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
862 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
866 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
874void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &
MBB)
const {
888 MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
890 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
891 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
892 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
893 NumBytes += RegisterSavedAreaSizePlusPadding;
896 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
904 unsigned RetOpc = RetI ? RetI->
getOpcode() : 0;
907 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
910 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
913 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
925 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
926 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
927 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
928 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
945 bool NeedsDeallocframe =
true;
946 unsigned PrevOpc = 0;
949 PrevOpc = PrevIt->getOpcode();
950 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
951 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
952 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
953 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
954 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
955 NeedsDeallocframe =
false;
958 if (!MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
960 if (!NeedsDeallocframe) {
966 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
967 PrevOpc != Hexagon::PS_callr_nr)
969 "-ffixed-r19 should have prevented this");
976 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
985 unsigned NewOpc = Hexagon::L4_return;
986 MachineInstr *NewI =
BuildMI(
MBB, RetI, dl, HII.get(NewOpc))
995 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
996 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
997 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
1002 bool HasRestoreStub =
1004 (
I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1006 Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1007 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1008 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC);
1009 if (!HasRestoreStub)
1010 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1013 if (RegisterSavedAreaSizePlusPadding != 0)
1014 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1016 .
addImm(RegisterSavedAreaSizePlusPadding);
1020 if (NeedsSCS && !HasRestoreStub)
1025void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &
MBB,
1034 const unsigned int ALLOCFRAME_MAX = 16384;
1044 auto *TLI = HST.getTargetLowering();
1045 bool NeedsProbing = TLI->hasInlineStackProbe(MF) && NumBytes > 0;
1046 unsigned ProbeSize = 0;
1049 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1052 if (NeedsProbing && NumBytes > ProbeSize) {
1054 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1062 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
1068 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
1071 }
else if (NumBytes >= ALLOCFRAME_MAX) {
1073 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1082 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1087 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1102 if (
MI.getOpcode() == Hexagon::PS_probed_stackalloc)
1107 auto *TLI = HST.getTargetLowering();
1109 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1115 Register TargetReg =
MI->getOperand(0).getReg();
1122 MF.
insert(InsertPt, LoopMBB);
1125 MF.
insert(InsertPt, ExitMBB);
1146 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi),
1152 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
1158 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
1164 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
1170 BuildMI(*ExitMBB, ExitMBB->
begin(),
DL, HII.get(Hexagon::A2_tfr),
1176 MBB->addSuccessor(LoopMBB);
1181 MI->eraseFromParent();
1198 for (
unsigned i = 0; i < Worklist.
size(); ++i) {
1199 unsigned BN = Worklist[i];
1202 if (!
MBB.isLiveIn(R.getReg()))
1203 MBB.addLiveIn(R.getReg());
1205 for (
auto &SB :
MBB.successors())
1206 Worklist.
insert(SB->getNumber());
1210bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &
MBB,
1211 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
1212 BitVector &Path)
const {
1215 if (Path[BN] || DoneF[BN])
1223 bool ReachedExit =
false;
1225 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
1231 MachineInstr &RetI =
MBB.
back();
1241 if (ReachedExit && &
MBB != &RestoreB) {
1254static std::optional<MachineBasicBlock::iterator>
1261 auto End =
B.instr_end();
1265 if (!
I.isBundle()) {
1266 if (
I.getOpcode() == Hexagon::S2_allocframe)
1267 return std::next(It);
1271 bool HasCall =
false, HasAllocFrame =
false;
1273 while (++
T != End &&
T->isBundled()) {
1274 if (
T->getOpcode() == Hexagon::S2_allocframe)
1275 HasAllocFrame =
true;
1276 else if (
T->isCall())
1280 return HasCall ? It : std::next(It);
1282 return std::nullopt;
1288 insertCFIInstructionsAt(
B, *At);
1303 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1306 bool HasFP = hasFP(MF);
1309 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(),
true);
1310 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(),
true);
1337 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1338 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1339 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1340 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1341 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1342 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1348 auto IfR = [
Reg] (
const CalleeSavedInfo &
C) ->
bool {
1349 return C.getReg() ==
Reg;
1368 getFrameIndexReference(MF,
F->getFrameIdx(), FrameReg).getFixed();
1374 unsigned DwarfReg = HRI.getDwarfRegNum(
Reg,
true);
1386 Register HiReg = HRI.getSubReg(
Reg, Hexagon::isub_hi);
1387 Register LoReg = HRI.getSubReg(
Reg, Hexagon::isub_lo);
1388 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg,
true);
1389 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg,
true);
1405 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1421 if (HasAlloca || HasExtraAlign)
1451 bool Stkchk =
false) {
1452 const char * V4SpillToMemoryFunctions[] = {
1453 "__save_r16_through_r17",
1454 "__save_r16_through_r19",
1455 "__save_r16_through_r21",
1456 "__save_r16_through_r23",
1457 "__save_r16_through_r25",
1458 "__save_r16_through_r27" };
1460 const char * V4SpillToMemoryStkchkFunctions[] = {
1461 "__save_r16_through_r17_stkchk",
1462 "__save_r16_through_r19_stkchk",
1463 "__save_r16_through_r21_stkchk",
1464 "__save_r16_through_r23_stkchk",
1465 "__save_r16_through_r25_stkchk",
1466 "__save_r16_through_r27_stkchk" };
1468 const char * V4SpillFromMemoryFunctions[] = {
1469 "__restore_r16_through_r17_and_deallocframe",
1470 "__restore_r16_through_r19_and_deallocframe",
1471 "__restore_r16_through_r21_and_deallocframe",
1472 "__restore_r16_through_r23_and_deallocframe",
1473 "__restore_r16_through_r25_and_deallocframe",
1474 "__restore_r16_through_r27_and_deallocframe" };
1476 const char * V4SpillFromMemoryTailcallFunctions[] = {
1477 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1478 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1479 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1480 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1481 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1482 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1485 const char **SpillFunc =
nullptr;
1489 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1490 : V4SpillToMemoryFunctions;
1493 SpillFunc = V4SpillFromMemoryFunctions;
1496 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1499 assert(SpillFunc &&
"Unknown spill kind");
1504 return SpillFunc[0];
1506 return SpillFunc[1];
1508 return SpillFunc[2];
1510 return SpillFunc[3];
1512 return SpillFunc[4];
1514 return SpillFunc[5];
1529 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1534 Register SP = HRI.getStackRegister();
1536 Register AP = HMFI.getStackAlignBaseReg();
1551 bool UseFP =
false, UseAP =
false;
1556 if (NoOpt && !HasExtraAlign)
1561 UseFP |= (HasAlloca || HasExtraAlign);
1572 bool HasFP =
hasFP(MF);
1573 assert((HasFP || !UseFP) &&
"This function must have frame pointer");
1599 if (
Offset > 0 && !HasFP)
1614 if (!UseFP && !UseAP)
1615 RealOffset = FrameSize+
Offset;
1621 bool &PrologueStubs)
const {
1626 PrologueStubs =
false;
1631 if (useSpillFunction(MF, CSI)) {
1632 PrologueStubs =
true;
1644 if (StkOvrFlowEnabled) {
1646 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1647 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1649 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1650 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1653 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1654 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1656 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1657 : Hexagon::SAVE_REGISTERS_CALL_V4;
1660 MachineInstr *SaveRegsCall =
1665 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI,
false,
true);
1667 for (
const CalleeSavedInfo &
I : CSI)
1670 for (
const CalleeSavedInfo &
I : CSI) {
1671 MCRegister
Reg =
I.getReg();
1676 int FI =
I.getFrameIdx();
1677 const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(
Reg);
1690 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
1691 if (
const MachineInstr *AlignaI = HFI.getAlignaInstr(MF)) {
1692 MachineInstr *AI =
const_cast<MachineInstr *
>(AlignaI);
1705bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &
MBB,
1706 const CSIVect &CSI,
const HexagonRegisterInfo &HRI)
const {
1715 if (useRestoreFunction(MF, CSI)) {
1720 auto &HTM =
static_cast<const HexagonTargetMachine&
>(MF.
getTarget());
1721 bool IsPIC = HTM.isPositionIndependent();
1727 MachineInstr *DeallocCall =
nullptr;
1732 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1733 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1735 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1736 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1745 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1746 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1748 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1749 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1755 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI,
true,
false);
1759 for (
const CalleeSavedInfo &
I : CSI) {
1760 MCRegister
Reg =
I.getReg();
1761 const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(
Reg);
1762 int FI =
I.getFrameIdx();
1773 unsigned Opc =
MI.getOpcode();
1775 assert((
Opc == Hexagon::ADJCALLSTACKDOWN ||
Opc == Hexagon::ADJCALLSTACKUP) &&
1776 "Cannot handle this call frame pseudo instruction");
1777 return MBB.erase(
I);
1790 if (!HasAlloca || !NeedsAlign)
1796 AP = AI->getOperand(0).getReg();
1799 HMFI.setStackAlignBaseReg(AP);
1807 auto IsUsed = [&HRI,&MRI] (
Register Reg) ->
bool {
1839 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1869 bool HasResSub =
false;
1895 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1901 for (
int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1939 int64_t MinOffset = 0;
1941 for (
const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1946 MinOffset = std::min(MinOffset, S->Offset);
1948 SRegs[S->Reg] =
false;
1957 unsigned Size =
TRI->getSpillSize(*RC);
1958 int64_t Off = MinOffset -
Size;
1960 Off &= -Alignment.
value();
1962 MinOffset = std::min(MinOffset, Off);
1968 dbgs() <<
"CS information: {";
1970 int FI =
I.getFrameIdx();
1982 bool MissedReg =
false;
2002 if (!Hexagon::ModRegsRegClass.
contains(DstR) ||
2003 !Hexagon::ModRegsRegClass.
contains(SrcR))
2007 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), TmpR).
add(
MI->getOperand(1));
2008 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), DstR)
2020 if (!
MI->getOperand(0).isFI())
2024 unsigned Opc =
MI->getOpcode();
2026 bool IsKill =
MI->getOperand(2).isKill();
2027 int FI =
MI->getOperand(0).getIndex();
2032 unsigned TfrOpc = (
Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2038 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2049bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &
B,
2051 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2052 MachineInstr *
MI = &*It;
2053 if (!
MI->getOperand(1).isFI())
2057 unsigned Opc =
MI->getOpcode();
2059 int FI =
MI->getOperand(1).getIndex();
2063 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2070 unsigned TfrOpc = (
Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2071 : Hexagon::A2_tfrrcr;
2073 .
addReg(TmpR, RegState::Kill);
2080bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &
B,
2082 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2083 MachineInstr *
MI = &*It;
2084 if (!
MI->getOperand(0).isFI())
2089 bool IsKill =
MI->getOperand(2).isKill();
2090 int FI =
MI->getOperand(0).getIndex();
2091 auto *RC = &Hexagon::HvxVRRegClass;
2100 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2103 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2105 .
addReg(TmpR0, RegState::Kill);
2108 expandStoreVec(
B, std::prev(It), MRI, HII, NewRegs);
2116bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &
B,
2118 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2119 MachineInstr *
MI = &*It;
2120 if (!
MI->getOperand(1).isFI())
2125 int FI =
MI->getOperand(1).getIndex();
2126 auto *RC = &Hexagon::HvxVRRegClass;
2134 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2137 expandLoadVec(
B, std::prev(It), MRI, HII, NewRegs);
2139 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandvrt), DstR)
2140 .
addReg(TmpR1, RegState::Kill)
2141 .
addReg(TmpR0, RegState::Kill);
2149bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &
B,
2151 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2152 MachineFunction &MF = *
B.getParent();
2154 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2155 MachineInstr *
MI = &*It;
2156 if (!
MI->getOperand(0).isFI())
2163 LivePhysRegs LPR(HRI);
2166 for (
auto R =
B.begin(); R != It; ++R) {
2168 LPR.stepForward(*R, Clobbers);
2173 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2174 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2175 bool IsKill =
MI->getOperand(2).isKill();
2176 int FI =
MI->getOperand(0).getIndex();
2178 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2179 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2184 if (LPR.contains(SrcLo)) {
2185 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2186 : Hexagon::V6_vS32Ub_ai;
2195 if (LPR.contains(SrcHi)) {
2196 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2197 : Hexagon::V6_vS32Ub_ai;
2209bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &
B,
2211 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2212 MachineFunction &MF = *
B.getParent();
2214 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2215 MachineInstr *
MI = &*It;
2216 if (!
MI->getOperand(1).isFI())
2221 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2222 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2223 int FI =
MI->getOperand(1).getIndex();
2225 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2226 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2231 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2232 : Hexagon::V6_vL32Ub_ai;
2239 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2240 : Hexagon::V6_vL32Ub_ai;
2250bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &
B,
2252 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2253 MachineFunction &MF = *
B.getParent();
2255 MachineInstr *
MI = &*It;
2256 if (!
MI->getOperand(0).isFI())
2259 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2262 bool IsKill =
MI->getOperand(2).isKill();
2263 int FI =
MI->getOperand(0).getIndex();
2265 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2267 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2268 : Hexagon::V6_vS32Ub_ai;
2279bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &
B,
2281 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2282 MachineFunction &MF = *
B.getParent();
2284 MachineInstr *
MI = &*It;
2285 if (!
MI->getOperand(1).isFI())
2288 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2291 int FI =
MI->getOperand(1).getIndex();
2293 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2295 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2296 : Hexagon::V6_vL32Ub_ai;
2306bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF,
2307 SmallVectorImpl<Register> &NewRegs)
const {
2308 auto &HII = *MF.
getSubtarget<HexagonSubtarget>().getInstrInfo();
2312 for (
auto &
B : MF) {
2315 for (
auto I =
B.begin(),
E =
B.end();
I !=
E;
I = NextI) {
2316 MachineInstr *
MI = &*
I;
2317 NextI = std::next(
I);
2318 unsigned Opc =
MI->getOpcode();
2321 case TargetOpcode::COPY:
2322 Changed |= expandCopy(
B,
I, MRI, HII, NewRegs);
2324 case Hexagon::STriw_pred:
2325 case Hexagon::STriw_ctr:
2326 Changed |= expandStoreInt(
B,
I, MRI, HII, NewRegs);
2328 case Hexagon::LDriw_pred:
2329 case Hexagon::LDriw_ctr:
2330 Changed |= expandLoadInt(
B,
I, MRI, HII, NewRegs);
2332 case Hexagon::PS_vstorerq_ai:
2333 Changed |= expandStoreVecPred(
B,
I, MRI, HII, NewRegs);
2335 case Hexagon::PS_vloadrq_ai:
2336 Changed |= expandLoadVecPred(
B,
I, MRI, HII, NewRegs);
2338 case Hexagon::PS_vloadrw_ai:
2339 Changed |= expandLoadVec2(
B,
I, MRI, HII, NewRegs);
2341 case Hexagon::PS_vstorerw_ai:
2342 Changed |= expandStoreVec2(
B,
I, MRI, HII, NewRegs);
2356 SavedRegs.
resize(HRI.getNumRegs());
2366 expandSpillMacros(MF, NewRegs);
2368 optimizeSpillSlots(MF, NewRegs);
2372 if (!NewRegs.
empty() || mayOverflowFrameOffset(MF)) {
2378 SpillRCs.
insert(&Hexagon::IntRegsRegClass);
2383 for (
const auto *RC : SpillRCs) {
2387 switch (RC->
getID()) {
2388 case Hexagon::IntRegsRegClassID:
2391 case Hexagon::HvxQRRegClassID:
2395 unsigned S = HRI.getSpillSize(*RC);
2396 Align A = HRI.getSpillAlign(*RC);
2397 for (
unsigned i = 0; i < Num; i++) {
2399 RS->addScavengingFrameIndex(NewFI);
2416 auto F = DeadMap.find({Reg,0});
2417 if (
F == DeadMap.end())
2419 for (
auto &DR :
F->second)
2420 if (DR.contains(FIR))
2439void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
2440 SmallVectorImpl<Register> &VRegs)
const {
2442 auto &HII = *HST.getInstrInfo();
2443 auto &HRI = *HST.getRegisterInfo();
2445 HexagonBlockRanges HBR(MF);
2447 using BlockIndexMap =
2448 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2449 using BlockRangeMap =
2450 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2451 using IndexType = HexagonBlockRanges::IndexType;
2456 const TargetRegisterClass *RC =
nullptr;
2458 SlotInfo() =
default;
2461 BlockIndexMap BlockIndexes;
2462 SmallSet<int,4> BadFIs;
2463 std::map<int,SlotInfo> FIRangeMap;
2470 [](
const TargetRegisterClass *HaveRC,
2471 const TargetRegisterClass *NewRC) ->
const TargetRegisterClass * {
2472 if (HaveRC ==
nullptr || HaveRC == NewRC)
2477 if (NewRC->hasSubClassEq(HaveRC))
2484 for (
auto &
B : MF) {
2485 std::map<int,IndexType> LastStore, LastLoad;
2486 auto P = BlockIndexes.emplace(&
B, HexagonBlockRanges::InstrIndexMap(
B));
2487 auto &IndexMap =
P.first->second;
2489 << IndexMap <<
'\n');
2491 for (
auto &In :
B) {
2493 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2494 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2495 if (Load && Store) {
2507 if (Load || Store) {
2508 int TFI =
Load ? LFI : SFI;
2509 unsigned AM = HII.getAddrMode(In);
2510 SlotInfo &
SI = FIRangeMap[TFI];
2514 unsigned OpNum =
Load ? 0 : 2;
2515 auto *RC = HII.getRegClass(
In.getDesc(), OpNum);
2516 RC = getCommonRC(
SI.RC, RC);
2524 unsigned S = HII.getMemAccessSize(In);
2525 if (
SI.Size != 0 &&
SI.Size != S)
2531 for (
auto *Mo :
In.memoperands()) {
2532 if (!Mo->isVolatile() && !Mo->isAtomic())
2543 for (
unsigned i = 0, n =
In.getNumOperands(); i < n; ++i) {
2544 const MachineOperand &
Op =
In.getOperand(i);
2547 int FI =
Op.getIndex();
2550 if (i+1 >= n || !
In.getOperand(i+1).isImm() ||
2551 In.getOperand(i+1).getImm() != 0)
2553 if (BadFIs.
count(FI))
2557 auto &
LS = LastStore[FI];
2558 auto &LL = LastLoad[FI];
2560 if (LS == IndexType::None)
2561 LS = IndexType::Entry;
2564 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2565 if (LS != IndexType::None)
2566 RL.
add(LS, LL,
false,
false);
2567 else if (LL != IndexType::None)
2568 RL.
add(IndexType::Entry, LL,
false,
false);
2569 LL = IndexType::None;
2577 for (
auto &
I : LastLoad) {
2578 IndexType LL =
I.second;
2579 if (LL == IndexType::None)
2581 auto &RL = FIRangeMap[
I.first].Map[&
B];
2582 IndexType &
LS = LastStore[
I.first];
2583 if (LS != IndexType::None)
2584 RL.
add(LS, LL,
false,
false);
2586 RL.
add(IndexType::Entry, LL,
false,
false);
2587 LS = IndexType::None;
2589 for (
auto &
I : LastStore) {
2590 IndexType
LS =
I.second;
2591 if (LS == IndexType::None)
2593 auto &RL = FIRangeMap[
I.first].Map[&
B];
2594 RL.
add(LS, IndexType::None,
false,
false);
2599 for (
auto &
P : FIRangeMap) {
2600 dbgs() <<
"fi#" <<
P.first;
2601 if (BadFIs.
count(
P.first))
2604 if (
P.second.RC !=
nullptr)
2605 dbgs() << HRI.getRegClassName(
P.second.RC) <<
'\n';
2607 dbgs() <<
"<null>\n";
2608 for (
auto &R :
P.second.Map)
2617 SmallSet<int,4> LoxFIs;
2619 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2621 for (
auto &
P : FIRangeMap) {
2623 if (BadFIs.
count(
P.first))
2625 for (
auto &
B : MF) {
2626 auto F =
P.second.Map.find(&
B);
2628 if (
F ==
P.second.Map.end() ||
F->second.empty())
2630 HexagonBlockRanges::IndexRange &
IR =
F->second.front();
2631 if (
IR.start() == IndexType::Entry)
2632 LoxFIs.insert(
P.first);
2633 BlockFIMap[&
B].push_back(
P.first);
2638 dbgs() <<
"Block-to-FI map (* -- live-on-exit):\n";
2639 for (
auto &
P : BlockFIMap) {
2640 auto &FIs =
P.second;
2644 for (
auto I : FIs) {
2645 dbgs() <<
" fi#" <<
I;
2646 if (LoxFIs.count(
I))
2658 for (
auto &
B : MF) {
2659 auto F = BlockIndexes.find(&
B);
2660 assert(
F != BlockIndexes.end());
2661 HexagonBlockRanges::InstrIndexMap &IM =
F->second;
2665 << HexagonBlockRanges::PrintRangeMap(
DM, HRI));
2667 for (
auto FI : BlockFIMap[&
B]) {
2668 if (BadFIs.
count(FI))
2671 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2672 for (
auto &
Range : RL) {
2674 if (!IndexType::isInstr(
Range.start()) ||
2675 !IndexType::isInstr(
Range.end()))
2679 assert(
SI.mayStore() &&
"Unexpected start instruction");
2681 MachineOperand &SrcOp =
SI.getOperand(2);
2683 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.
getReg(),
2685 auto *RC = HII.getRegClass(
SI.getDesc(), 2);
2702 MachineInstr *CopyIn =
nullptr;
2703 if (SrcRR.
Reg != FoundR || SrcRR.
Sub != 0) {
2705 CopyIn =
BuildMI(
B, StartIt,
DL, HII.get(TargetOpcode::COPY), FoundR)
2711 if (LoxFIs.count(FI) && (&
Range == &RL.back())) {
2714 SrcOp.
setReg(HRI.getSubReg(FoundR, SR));
2726 for (
auto It = StartIt; It != EndIt; It = NextIt) {
2727 MachineInstr &
MI = *It;
2728 NextIt = std::next(It);
2730 if (!HII.isLoadFromStackSlot(
MI, TFI) || TFI != FI)
2733 assert(
MI.getOperand(0).getSubReg() == 0);
2734 MachineInstr *CopyOut =
nullptr;
2735 if (DstR != FoundR) {
2737 unsigned MemSize = HII.getMemAccessSize(
MI);
2739 unsigned CopyOpc = TargetOpcode::COPY;
2740 if (HII.isSignExtendingLoad(
MI))
2741 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2742 else if (HII.isZeroExtendingLoad(
MI))
2743 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2744 CopyOut =
BuildMI(
B, It,
DL, HII.get(CopyOpc), DstR)
2752 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2760void HexagonFrameLowering::expandAlloca(MachineInstr *AI, MachineFunction &MF,
2761 const HexagonInstrInfo &HII,
2763 MachineBasicBlock &MB = *AI->
getParent();
2773 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2775 if (!NeedsProbing) {
2799 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2803 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), SP)
2841 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2846 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_sub), Rd)
2852 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2861 MF.
insert(InsertPt, LoopMBB);
2863 MF.
insert(InsertPt, ExitMBB);
2874 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2879 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
2885 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
2891 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
2900 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
2904 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_addi), Rd)
2934 if (
I.getOpcode() == Hexagon::PS_aligna)
2941void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(
MachineInstr *
MI,
2942 const CSIVect &CSI,
bool IsDef,
bool IsKill)
const {
2953 const CSIVect &CSI)
const {
2966 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2969 if (!Hexagon::DoubleRegsRegClass.
contains(R))
2973 int F = Regs.find_first();
2974 if (
F != Hexagon::D8)
2977 int N = Regs.find_next(
F);
2978 if (
N >= 0 &&
N !=
F+1)
2986bool HexagonFrameLowering::useSpillFunction(
const MachineFunction &MF,
2987 const CSIVect &CSI)
const {
2988 if (shouldInlineCSR(MF, CSI))
2990 unsigned NumCSI = CSI.size();
2996 return Threshold < NumCSI;
2999bool HexagonFrameLowering::useRestoreFunction(
const MachineFunction &MF,
3000 const CSIVect &CSI)
const {
3001 if (shouldInlineCSR(MF, CSI))
3011 unsigned NumCSI = CSI.size();
3017 return Threshold < NumCSI;
3020bool HexagonFrameLowering::mayOverflowFrameOffset(MachineFunction &MF)
const {
3025 if (HST.useHVXOps() && StackSize > 256)
3032 bool HasImmStack =
false;
3033 unsigned MinLS = ~0
u;
3035 for (
const MachineBasicBlock &
B : MF) {
3036 for (
const MachineInstr &
MI :
B) {
3038 switch (
MI.getOpcode()) {
3039 case Hexagon::S4_storeirit_io:
3040 case Hexagon::S4_storeirif_io:
3041 case Hexagon::S4_storeiri_io:
3044 case Hexagon::S4_storeirht_io:
3045 case Hexagon::S4_storeirhf_io:
3046 case Hexagon::S4_storeirh_io:
3049 case Hexagon::S4_storeirbt_io:
3050 case Hexagon::S4_storeirbf_io:
3051 case Hexagon::S4_storeirb_io:
3052 if (
MI.getOperand(0).isFI())
3054 MinLS = std::min(MinLS, LS);
3068struct HexagonFrameSortingObject {
3069 bool IsValid =
false;
3075struct HexagonFrameSortingComparator {
3076 inline bool operator()(
const HexagonFrameSortingObject &
A,
3077 const HexagonFrameSortingObject &
B)
const {
3078 return std::make_tuple(!
A.IsValid,
A.ObjectAlignment,
A.Size) <
3079 std::make_tuple(!
B.IsValid,
B.ObjectAlignment,
B.Size);
3089 if (ObjectsToAllocate.
empty())
3093 int NObjects = ObjectsToAllocate.
size();
3101 if (i != ObjectsToAllocate[j])
3112 SortingObjects[i].IsValid =
true;
3113 SortingObjects[i].Index = i;
3123 for (
auto &Obj : SortingObjects) {
3126 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< 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.
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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
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.
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...
unsigned getID() const
Return the register class ID number.
ArrayRef< MCPhysReg > getRawAllocationOrder(const MachineFunction &MF, bool Rev=false) const
Returns the preferred order for allocating registers from this register class in MF.
bool hasSubClassEq(const TargetRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool isRegisterReservedByUser(Register R) const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
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)
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
MaybeAlign getStackAlign(const CallBase &I, unsigned Index)
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.
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.
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.