67#define DEBUG_TYPE "hexagon-pei"
162 if (!HST.getFrameLowering()->hasFP(MF))
173 Register SCSPReg = HST.getSCSPReg();
174 const auto &HRI = *HST.getRegisterInfo();
175 if (!HST.isRegisterReservedByUser(SCSPReg))
180 " to use shadow call stack on Hexagon");
182 const auto &HII = *HST.getInstrInfo();
196 MBB.addLiveIn(SCSPReg);
203 unsigned DwarfSCSReg = HRI.getDwarfRegNum(SCSPReg,
true);
206 assert(DwarfSCSReg < 32 &&
"SCS register should be < 32");
207 const char CFIInst[] = {
208 (
char)dwarf::DW_CFA_val_expression,
211 (
char)(
unsigned)(dwarf::DW_OP_breg0 + DwarfSCSReg),
231 Register SCSPReg = HST.getSCSPReg();
232 const auto &HII = *HST.getInstrInfo();
235 BuildMI(
MBB,
MI,
DL, HII.get(Hexagon::L2_loadri_io), Hexagon::R31)
254 cl::desc(
"Set the number of scavenger slots"),
259 cl::desc(
"Specify O2(not Os) spill func threshold"),
264 cl::desc(
"Specify Os spill func threshold"),
273 cl::desc(
"Enable stack frame shrink wrapping"));
278 cl::desc(
"Max count of stack frame shrink-wraps"));
282 cl::desc(
"Enable long calls for save-restore stubs."),
293 cl::init(std::numeric_limits<unsigned>::max()));
312 char HexagonCallFrameInformation::ID = 0;
316bool HexagonCallFrameInformation::runOnMachineFunction(
MachineFunction &MF) {
317 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
322 HFI.insertCFIInstructions(MF);
327 "Hexagon call frame information",
false,
false)
330 return new HexagonCallFrameInformation();
347 if (!RegNo || SubReg < RegNo)
357 static_assert(Hexagon::R1 > 0,
358 "Assume physical registers are encoded as positive integers");
363 for (
unsigned I = 1,
E = CSI.
size();
I <
E; ++
I) {
384 unsigned Opc =
MI.getOpcode();
386 case Hexagon::PS_alloca:
409 for (
MCPhysReg S : HRI.subregs_inclusive(R))
414 if (MO.isRegMask()) {
419 const uint32_t *BM = MO.getRegMask();
423 if (!(BM[R / 32] & (1u << (R % 32))))
438 unsigned RetOpc =
I->getOpcode();
439 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
461 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
462 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
463 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
464 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
465 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
466 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
467 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
468 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
481 return F.hasOptSize() && !
F.hasMinSize();
493 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB)
const {
494 static unsigned ShrinkCounter = 0;
496 if (MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
505 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
507 MachineDominatorTree MDT;
509 MachinePostDominatorTree MPT;
512 using UnsignedMap = DenseMap<unsigned, unsigned>;
513 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
519 RPO[
I->getNumber()] = RPON++;
525 unsigned BN = RPO[
I.getNumber()];
526 for (MachineBasicBlock *Succ :
I.successors())
528 if (RPO[Succ->getNumber()] <= BN)
535 BitVector CSR(Hexagon::NUM_TARGET_REGS);
536 for (
const MCPhysReg *
P = HRI.getCalleeSavedRegs(&MF); *
P; ++
P)
545 dbgs() <<
"Blocks needing SF: {";
546 for (
auto &
B : SFBlocks)
551 if (SFBlocks.
empty())
555 MachineBasicBlock *DomB = SFBlocks[0];
556 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
561 MachineBasicBlock *PDomB = SFBlocks[0];
562 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
568 dbgs() <<
"Computed dom block: ";
573 dbgs() <<
", computed pdom block: ";
589 LLVM_DEBUG(
dbgs() <<
"PDom block does not post-dominate dom block\n");
612 findShrunkPrologEpilog(MF, PrologB, EpilogB);
614 bool PrologueStubs =
false;
616 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
622 insertAlignaInBlock(*PrologB, AfterCSR);
623 insertPrologueInBlock(*PrologB, PrologueStubs);
631 while (AfterProlog != PrologB->
end() &&
637 updateEntryPaths(MF, *PrologB);
640 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
641 insertEpilogueInBlock(*EpilogB);
644 if (
B.isReturnBlock())
645 insertCSRRestoresInBlock(
B, CSI, HRI);
648 if (
B.isReturnBlock())
649 insertEpilogueInBlock(
B);
667 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
668 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
677 assert(
F.hasFnAttribute(Attribute::NoReturn) &&
678 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
679 !
F.getFunction().hasFnAttribute(Attribute::UWTable));
695 assert(!MFI.hasVarSizedObjects() &&
696 !HST.getRegisterInfo()->hasStackRealignment(MF));
697 return F.hasFnAttribute(Attribute::NoReturn) &&
698 F.hasFnAttribute(Attribute::NoUnwind) &&
699 !
F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
700 MFI.getStackSize() == 0;
703void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &
MBB,
704 bool PrologueStubs)
const {
720 FrameSize = MaxCFA +
alignTo(FrameSize, MaxAlign);
731 SmallVector<MachineInstr *, 4> AdjustRegs;
734 if (
MI.getOpcode() == Hexagon::PS_alloca)
737 for (
auto *
MI : AdjustRegs) {
738 assert((
MI->getOpcode() == Hexagon::PS_alloca) &&
"Expected alloca");
739 expandAlloca(
MI, MF, HII, SP, MaxCF);
740 MI->eraseFromParent();
745 if (MF.getFunction().isVarArg() &&
746 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
748 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
749 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
751 : NumVarArgRegs * 4 + 4;
752 if (RegisterSavedAreaSizePlusPadding > 0) {
755 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
757 .
addImm(-RegisterSavedAreaSizePlusPadding)
762 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
763 for (
int i = HMFI.getFirstNamedArgFrameIndex(),
764 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
769 unsigned LDOpc, STOpc;
773 if (ObjAlign > ObjSize) {
776 else if (ObjSize <= 2)
778 else if (ObjSize <= 4)
780 else if (ObjSize > 4)
784 switch (OpcodeChecker) {
786 LDOpc = Hexagon::L2_loadrb_io;
787 STOpc = Hexagon::S2_storerb_io;
790 LDOpc = Hexagon::L2_loadrh_io;
791 STOpc = Hexagon::S2_storerh_io;
794 LDOpc = Hexagon::L2_loadri_io;
795 STOpc = Hexagon::S2_storeri_io;
799 LDOpc = Hexagon::L2_loadrd_io;
800 STOpc = Hexagon::S2_storerd_io;
804 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
806 int LoadStoreCount = ObjSize / OpcodeChecker;
808 if (ObjSize % OpcodeChecker)
816 NumBytes =
alignTo(NumBytes, ObjAlign);
819 while (
Count < LoadStoreCount) {
821 BuildMI(
MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
823 .
addImm(RegisterSavedAreaSizePlusPadding +
840 NumBytes =
alignTo(NumBytes, 8);
845 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
847 for (
int j = FirstVarArgSavedReg, i = 0;
j < 6; ++
j, ++i) {
848 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
858 insertAllocframe(
MBB, InsertPt, NumBytes);
860 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
868 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
870 }
else if (NumBytes > 0) {
872 auto *TLI = HST.getTargetLowering();
873 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
874 unsigned ProbeSize = 0;
877 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
879 if (NeedsProbing && NumBytes > ProbeSize) {
881 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
886 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
890 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
898void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &
MBB)
const {
912 MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
914 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
915 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
916 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
917 NumBytes += RegisterSavedAreaSizePlusPadding;
920 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
928 unsigned RetOpc = RetI ? RetI->
getOpcode() : 0;
931 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
934 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
937 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
948 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
949 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
950 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
951 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
968 bool NeedsDeallocframe =
true;
969 unsigned PrevOpc = 0;
972 PrevOpc = PrevIt->getOpcode();
973 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
974 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
975 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
976 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
977 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
978 NeedsDeallocframe =
false;
981 if (!MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
983 if (!NeedsDeallocframe) {
988 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
989 PrevOpc != Hexagon::PS_callr_nr)
991 "useRestoreFunction() should have prevented this");
998 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1007 unsigned NewOpc = Hexagon::L4_return;
1008 MachineInstrBuilder NewI =
BuildMI(
MBB, RetI, dl, HII.get(NewOpc))
1018 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
1019 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
1020 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
1025 bool HasRestoreStub =
1027 (
I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1029 Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1030 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1031 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC);
1032 if (!HasRestoreStub)
1033 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1036 if (RegisterSavedAreaSizePlusPadding != 0)
1037 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1039 .
addImm(RegisterSavedAreaSizePlusPadding);
1043 if (NeedsSCS && !HasRestoreStub)
1048void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &
MBB,
1057 const unsigned int ALLOCFRAME_MAX = 16384;
1067 auto *TLI = HST.getTargetLowering();
1068 bool NeedsProbing = TLI->hasInlineStackProbe(MF) && NumBytes > 0;
1069 unsigned ProbeSize = 0;
1072 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1075 if (NeedsProbing && NumBytes > ProbeSize) {
1077 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1085 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
1091 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
1094 }
else if (NumBytes >= ALLOCFRAME_MAX) {
1096 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1105 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1110 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1125 if (
MI.getOpcode() == Hexagon::PS_probed_stackalloc)
1130 auto *TLI = HST.getTargetLowering();
1132 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1138 Register TargetReg =
MI->getOperand(0).getReg();
1145 MF.
insert(InsertPt, LoopMBB);
1148 MF.
insert(InsertPt, ExitMBB);
1169 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi),
1175 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
1181 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
1187 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
1193 BuildMI(*ExitMBB, ExitMBB->
begin(),
DL, HII.get(Hexagon::A2_tfr),
1199 MBB->addSuccessor(LoopMBB);
1204 MI->eraseFromParent();
1211void HexagonFrameLowering::insertAlignaInBlock(
1219 assert(needsAligna(MF) &&
"Unexpected stack align base register");
1224 BuildMI(
MBB, InsertPt,
DL, HII.get(Hexagon::PS_aligna), AP)
1238 for (
unsigned i = 0; i < Worklist.
size(); ++i) {
1239 unsigned BN = Worklist[i];
1242 if (!
MBB.isLiveIn(R.getReg()))
1243 MBB.addLiveIn(R.getReg());
1245 for (
auto &SB :
MBB.successors())
1246 Worklist.
insert(SB->getNumber());
1250bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &
MBB,
1251 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
1252 BitVector &Path)
const {
1255 if (Path[BN] || DoneF[BN])
1263 bool ReachedExit =
false;
1265 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
1271 MachineInstr &RetI =
MBB.
back();
1281 if (ReachedExit && &
MBB != &RestoreB) {
1294static std::optional<MachineBasicBlock::iterator>
1301 auto End =
B.instr_end();
1305 if (!
I.isBundle()) {
1306 if (
I.getOpcode() == Hexagon::S2_allocframe)
1307 return std::next(It);
1311 bool HasCall =
false, HasAllocFrame =
false;
1313 while (++
T !=
End &&
T->isBundled()) {
1314 if (
T->getOpcode() == Hexagon::S2_allocframe)
1315 HasAllocFrame =
true;
1316 else if (
T->isCall())
1320 return HasCall ? It : std::next(It);
1322 return std::nullopt;
1328 insertCFIInstructionsAt(
B, *At);
1343 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1346 bool HasFP = hasFP(MF);
1349 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(),
true);
1350 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(),
true);
1377 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1378 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1379 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1380 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1381 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1382 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1388 auto IfR = [
Reg] (
const CalleeSavedInfo &
C) ->
bool {
1389 return C.getReg() ==
Reg;
1408 getFrameIndexReference(MF,
F->getFrameIdx(), FrameReg).getFixed();
1414 unsigned DwarfReg = HRI.getDwarfRegNum(
Reg,
true);
1426 Register HiReg = HRI.getSubReg(
Reg, Hexagon::isub_hi);
1427 Register LoReg = HRI.getSubReg(
Reg, Hexagon::isub_lo);
1428 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg,
true);
1429 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg,
true);
1445 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1461 if (HasAlloca || HasExtraAlign)
1490 bool Stkchk =
false) {
1491 const char * V4SpillToMemoryFunctions[] = {
1492 "__save_r16_through_r17",
1493 "__save_r16_through_r19",
1494 "__save_r16_through_r21",
1495 "__save_r16_through_r23",
1496 "__save_r16_through_r25",
1497 "__save_r16_through_r27" };
1499 const char * V4SpillToMemoryStkchkFunctions[] = {
1500 "__save_r16_through_r17_stkchk",
1501 "__save_r16_through_r19_stkchk",
1502 "__save_r16_through_r21_stkchk",
1503 "__save_r16_through_r23_stkchk",
1504 "__save_r16_through_r25_stkchk",
1505 "__save_r16_through_r27_stkchk" };
1507 const char * V4SpillFromMemoryFunctions[] = {
1508 "__restore_r16_through_r17_and_deallocframe",
1509 "__restore_r16_through_r19_and_deallocframe",
1510 "__restore_r16_through_r21_and_deallocframe",
1511 "__restore_r16_through_r23_and_deallocframe",
1512 "__restore_r16_through_r25_and_deallocframe",
1513 "__restore_r16_through_r27_and_deallocframe" };
1515 const char * V4SpillFromMemoryTailcallFunctions[] = {
1516 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1517 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1518 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1519 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1520 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1521 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1524 const char **SpillFunc =
nullptr;
1528 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1529 : V4SpillToMemoryFunctions;
1532 SpillFunc = V4SpillFromMemoryFunctions;
1535 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1538 assert(SpillFunc &&
"Unknown spill kind");
1543 return SpillFunc[0];
1545 return SpillFunc[1];
1547 return SpillFunc[2];
1549 return SpillFunc[3];
1551 return SpillFunc[4];
1553 return SpillFunc[5];
1568 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1573 Register SP = HRI.getStackRegister();
1575 Register AP = HMFI.getStackAlignBaseReg();
1590 bool UseFP =
false, UseAP =
false;
1595 if (NoOpt && !HasExtraAlign)
1600 UseFP |= (HasAlloca || HasExtraAlign);
1611 bool HasFP =
hasFP(MF);
1612 assert((HasFP || !UseFP) &&
"This function must have frame pointer");
1638 if (
Offset > 0 && !HasFP)
1653 if (!UseFP && !UseAP)
1654 RealOffset = FrameSize+
Offset;
1660 bool &PrologueStubs)
const {
1665 PrologueStubs =
false;
1670 if (useSpillFunction(MF, CSI)) {
1671 PrologueStubs =
true;
1683 if (StkOvrFlowEnabled) {
1685 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1686 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1688 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1689 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1692 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1693 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1695 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1696 : Hexagon::SAVE_REGISTERS_CALL_V4;
1699 MachineInstr *SaveRegsCall =
1704 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI,
false,
true);
1706 for (
const CalleeSavedInfo &
I : CSI)
1709 for (
const CalleeSavedInfo &
I : CSI) {
1710 MCRegister
Reg =
I.getReg();
1715 int FI =
I.getFrameIdx();
1726bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &
MBB,
1727 const CSIVect &CSI,
const HexagonRegisterInfo &HRI)
const {
1736 if (useRestoreFunction(MF, CSI)) {
1741 auto &HTM =
static_cast<const HexagonTargetMachine&
>(MF.
getTarget());
1742 bool IsPIC = HTM.isPositionIndependent();
1748 MachineInstr *DeallocCall =
nullptr;
1753 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1754 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1756 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1757 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1766 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1767 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1769 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1770 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1771 MachineInstrBuilder MIB =
1775 for (
const MachineOperand &MO :
drop_begin(It->implicit_operands()))
1779 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI,
true,
false);
1783 for (
const CalleeSavedInfo &
I : CSI) {
1784 MCRegister
Reg =
I.getReg();
1786 int FI =
I.getFrameIdx();
1797 unsigned Opc =
MI.getOpcode();
1799 assert((
Opc == Hexagon::ADJCALLSTACKDOWN ||
Opc == Hexagon::ADJCALLSTACKUP) &&
1800 "Cannot handle this call frame pseudo instruction");
1801 return MBB.erase(
I);
1811 if (
MRI.isPhysRegUsed(*AI))
1841 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1868 "AP must be assigned before register allocation");
1873 bool HasResSub =
false;
1899 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1905 for (
int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1943 int64_t MinOffset = 0;
1945 for (
const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1950 MinOffset = std::min(MinOffset, S->Offset);
1952 SRegs[S->Reg] =
false;
1961 unsigned Size =
TRI->getSpillSize(*RC);
1962 int64_t
Off = MinOffset -
Size;
1964 Off &= -Alignment.value();
1966 MinOffset = std::min(MinOffset,
Off);
1972 dbgs() <<
"CS information: {";
1974 int FI =
I.getFrameIdx();
1986 bool MissedReg =
false;
2006 if (!Hexagon::ModRegsRegClass.
contains(DstR) ||
2007 !Hexagon::ModRegsRegClass.
contains(SrcR))
2010 Register TmpR =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2011 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), TmpR).
add(
MI->getOperand(1));
2012 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), DstR)
2024 if (!
MI->getOperand(0).isFI())
2028 unsigned Opc =
MI->getOpcode();
2030 bool IsKill =
MI->getOperand(2).isKill();
2031 int FI =
MI->getOperand(0).getIndex();
2035 Register TmpR =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2036 unsigned TfrOpc = (
Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2042 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2053bool HexagonFrameLowering::expandStoreCirc(
2055 MachineRegisterInfo &
MRI,
const HexagonInstrInfo &HII,
2056 SmallVectorImpl<Register> &NewRegs)
const {
2058 const auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2059 MachineInstr *
MI = &*It;
2060 if (!
MI->getOperand(0).isFI())
2065 bool IsKill =
MI->getOperand(1).isKill();
2066 int FI =
MI->getOperand(0).getIndex();
2069 for (
auto SubReg : {Hexagon::isub_lo, Hexagon::isub_hi}) {
2070 Register SrcSubReg = HRI.getSubReg(SrcR, SubReg);
2074 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrcrr), TmpR)
2079 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2082 .
addReg(TmpR, RegState::Kill)
2085 Offset += HRI.getSpillSize(Hexagon::IntRegsRegClass);
2092bool HexagonFrameLowering::expandLoadCirc(
2094 MachineRegisterInfo &
MRI,
const HexagonInstrInfo &HII,
2095 SmallVectorImpl<Register> &NewRegs)
const {
2097 const auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2098 MachineInstr *
MI = &*It;
2099 if (!
MI->getOperand(1).isFI())
2104 int FI =
MI->getOperand(1).getIndex();
2107 for (
auto SubReg : {Hexagon::isub_lo, Hexagon::isub_hi}) {
2108 Register DstSubReg = HRI.getSubReg(DstR, SubReg);
2112 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2118 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrrcr), DstSubReg)
2119 .
addReg(TmpR, RegState::Kill)
2123 Offset += HRI.getSpillSize(Hexagon::IntRegsRegClass);
2130bool HexagonFrameLowering::expandLoadInt(
2132 MachineRegisterInfo &
MRI,
const HexagonInstrInfo &HII,
2133 SmallVectorImpl<Register> &NewRegs)
const {
2134 MachineInstr *
MI = &*It;
2135 if (!
MI->getOperand(1).isFI())
2139 unsigned Opc =
MI->getOpcode();
2141 int FI =
MI->getOperand(1).getIndex();
2145 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2152 unsigned TfrOpc = (
Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2153 : Hexagon::A2_tfrrcr;
2155 .
addReg(TmpR, RegState::Kill);
2162bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &
B,
2164 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2165 MachineInstr *
MI = &*It;
2166 if (!
MI->getOperand(0).isFI())
2171 bool IsKill =
MI->getOperand(2).isKill();
2172 int FI =
MI->getOperand(0).getIndex();
2173 auto *RC = &Hexagon::HvxVRRegClass;
2182 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2185 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2187 .
addReg(TmpR0, RegState::Kill);
2190 expandStoreVec(
B, std::prev(It),
MRI, HII, NewRegs);
2198bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &
B,
2200 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2201 MachineInstr *
MI = &*It;
2202 if (!
MI->getOperand(1).isFI())
2207 int FI =
MI->getOperand(1).getIndex();
2208 auto *RC = &Hexagon::HvxVRRegClass;
2216 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2219 expandLoadVec(
B, std::prev(It),
MRI, HII, NewRegs);
2221 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandvrt), DstR)
2222 .
addReg(TmpR1, RegState::Kill)
2223 .
addReg(TmpR0, RegState::Kill);
2231bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &
B,
2233 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2236 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2237 MachineInstr *
MI = &*It;
2238 if (!
MI->getOperand(0).isFI())
2245 LivePhysRegs LPR(HRI);
2248 for (
auto R =
B.begin(); R != It; ++R) {
2250 LPR.stepForward(*R, Clobbers);
2255 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2256 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2257 bool IsKill =
MI->getOperand(2).isKill();
2258 int FI =
MI->getOperand(0).getIndex();
2260 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2261 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2266 if (LPR.contains(SrcLo)) {
2267 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2268 : Hexagon::V6_vS32Ub_ai;
2277 if (LPR.contains(SrcHi)) {
2278 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2279 : Hexagon::V6_vS32Ub_ai;
2291bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &
B,
2293 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2296 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2297 MachineInstr *
MI = &*It;
2298 if (!
MI->getOperand(1).isFI())
2303 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2304 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2305 int FI =
MI->getOperand(1).getIndex();
2307 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2308 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2313 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2314 : Hexagon::V6_vL32Ub_ai;
2321 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2322 : Hexagon::V6_vL32Ub_ai;
2332bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &
B,
2334 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2337 MachineInstr *
MI = &*It;
2338 if (!
MI->getOperand(0).isFI())
2341 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2344 bool IsKill =
MI->getOperand(2).isKill();
2345 int FI =
MI->getOperand(0).getIndex();
2347 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2349 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2350 : Hexagon::V6_vS32Ub_ai;
2361bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &
B,
2363 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2366 MachineInstr *
MI = &*It;
2367 if (!
MI->getOperand(1).isFI())
2370 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2373 int FI =
MI->getOperand(1).getIndex();
2375 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2377 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2378 : Hexagon::V6_vL32Ub_ai;
2389 SmallVectorImpl<Register> &NewRegs)
const {
2390 auto &HII = *MF.
getSubtarget<HexagonSubtarget>().getInstrInfo();
2394 for (
auto &
B : MF) {
2397 for (
auto I =
B.begin(),
E =
B.end();
I !=
E;
I = NextI) {
2398 MachineInstr *
MI = &*
I;
2399 NextI = std::next(
I);
2400 unsigned Opc =
MI->getOpcode();
2403 case TargetOpcode::COPY:
2406 case Hexagon::STriw_pred:
2407 case Hexagon::STriw_ctr:
2410 case Hexagon::STriw_circ:
2413 case Hexagon::LDriw_pred:
2414 case Hexagon::LDriw_ctr:
2417 case Hexagon::LDriw_circ:
2420 case Hexagon::PS_vstorerq_ai:
2421 Changed |= expandStoreVecPred(
B,
I,
MRI, HII, NewRegs);
2423 case Hexagon::PS_vloadrq_ai:
2426 case Hexagon::PS_vloadrw_ai:
2429 case Hexagon::PS_vstorerw_ai:
2444 SavedRegs.
resize(HRI.getNumRegs());
2458 assert(AP.
isValid() &&
"AP must be assigned before register allocation");
2464 expandSpillMacros(MF, NewRegs);
2466 optimizeSpillSlots(MF, NewRegs);
2470 if (!NewRegs.
empty() || mayOverflowFrameOffset(MF)) {
2476 SpillRCs.
insert(&Hexagon::IntRegsRegClass);
2481 for (
const auto *RC : SpillRCs) {
2485 switch (RC->
getID()) {
2486 case Hexagon::IntRegsRegClassID:
2489 case Hexagon::HvxQRRegClassID:
2493 unsigned S = HRI.getSpillSize(*RC);
2494 Align A = HRI.getSpillAlign(*RC);
2495 for (
unsigned i = 0; i < Num; i++) {
2497 RS->addScavengingFrameIndex(NewFI);
2514 auto F = DeadMap.find({Reg,0});
2515 if (
F == DeadMap.end())
2517 for (
auto &DR :
F->second)
2518 if (DR.contains(FIR))
2523 for (
Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2538 SmallVectorImpl<Register> &VRegs)
const {
2540 auto &HII = *HST.getInstrInfo();
2541 auto &HRI = *HST.getRegisterInfo();
2543 HexagonBlockRanges HBR(MF);
2545 using BlockIndexMap =
2546 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2547 using BlockRangeMap =
2548 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2549 using IndexType = HexagonBlockRanges::IndexType;
2556 SlotInfo() =
default;
2559 BlockIndexMap BlockIndexes;
2560 SmallSet<int,4> BadFIs;
2561 std::map<int,SlotInfo> FIRangeMap;
2570 if (HaveRC ==
nullptr || HaveRC == NewRC)
2575 if (NewRC->hasSubClassEq(HaveRC))
2582 for (
auto &
B : MF) {
2583 std::map<int,IndexType> LastStore, LastLoad;
2584 auto P = BlockIndexes.emplace(&
B, HexagonBlockRanges::InstrIndexMap(
B));
2585 auto &IndexMap =
P.first->second;
2587 << IndexMap <<
'\n');
2589 for (
auto &In :
B) {
2593 if (
In.isDebugInstr())
2596 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2597 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2611 int TFI =
Load ? LFI : SFI;
2612 unsigned AM = HII.getAddrMode(In);
2613 SlotInfo &
SI = FIRangeMap[TFI];
2617 unsigned OpNum =
Load ? 0 : 2;
2618 auto *RC = HII.getRegClass(
In.getDesc(), OpNum);
2619 RC = getCommonRC(
SI.RC, RC);
2627 unsigned S = HII.getMemAccessSize(In);
2628 if (
SI.Size != 0 &&
SI.Size != S)
2634 for (
auto *Mo :
In.memoperands()) {
2635 if (!Mo->isVolatile() && !Mo->isAtomic())
2646 for (
unsigned i = 0, n =
In.getNumOperands(); i < n; ++i) {
2647 const MachineOperand &
Op =
In.getOperand(i);
2650 int FI =
Op.getIndex();
2653 if (i+1 >= n || !
In.getOperand(i+1).isImm() ||
2654 In.getOperand(i+1).getImm() != 0)
2656 if (BadFIs.
count(FI))
2660 auto &
LS = LastStore[FI];
2661 auto &LL = LastLoad[FI];
2663 if (LS == IndexType::None)
2664 LS = IndexType::Entry;
2667 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2668 if (LS != IndexType::None)
2669 RL.
add(LS, LL,
false,
false);
2670 else if (LL != IndexType::None)
2671 RL.
add(IndexType::Entry, LL,
false,
false);
2672 LL = IndexType::None;
2680 for (
auto &
I : LastLoad) {
2681 IndexType LL =
I.second;
2682 if (LL == IndexType::None)
2684 auto &RL = FIRangeMap[
I.first].Map[&
B];
2685 IndexType &
LS = LastStore[
I.first];
2686 if (LS != IndexType::None)
2687 RL.
add(LS, LL,
false,
false);
2689 RL.
add(IndexType::Entry, LL,
false,
false);
2690 LS = IndexType::None;
2692 for (
auto &
I : LastStore) {
2693 IndexType
LS =
I.second;
2694 if (LS == IndexType::None)
2696 auto &RL = FIRangeMap[
I.first].Map[&
B];
2697 RL.
add(LS, IndexType::None,
false,
false);
2702 for (
auto &
P : FIRangeMap) {
2703 dbgs() <<
"fi#" <<
P.first;
2704 if (BadFIs.
count(
P.first))
2707 if (
P.second.RC !=
nullptr)
2708 dbgs() << HRI.getRegClassName(
P.second.RC) <<
'\n';
2710 dbgs() <<
"<null>\n";
2711 for (
auto &R :
P.second.Map)
2720 SmallSet<int,4> LoxFIs;
2722 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2724 for (
auto &
P : FIRangeMap) {
2726 if (BadFIs.
count(
P.first))
2728 for (
auto &
B : MF) {
2729 auto F =
P.second.Map.find(&
B);
2731 if (
F ==
P.second.Map.end() ||
F->second.empty())
2733 HexagonBlockRanges::IndexRange &
IR =
F->second.front();
2734 if (
IR.start() == IndexType::Entry)
2735 LoxFIs.insert(
P.first);
2736 BlockFIMap[&
B].push_back(
P.first);
2741 dbgs() <<
"Block-to-FI map (* -- live-on-exit):\n";
2742 for (
auto &
P : BlockFIMap) {
2743 auto &FIs =
P.second;
2747 for (
auto I : FIs) {
2748 dbgs() <<
" fi#" <<
I;
2749 if (LoxFIs.count(
I))
2761 for (
auto &
B : MF) {
2762 auto F = BlockIndexes.find(&
B);
2763 assert(
F != BlockIndexes.end());
2764 HexagonBlockRanges::InstrIndexMap &IM =
F->second;
2768 << HexagonBlockRanges::PrintRangeMap(
DM, HRI));
2770 for (
auto FI : BlockFIMap[&
B]) {
2771 if (BadFIs.
count(FI))
2774 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2775 for (
auto &
Range : RL) {
2777 if (!IndexType::isInstr(
Range.start()) ||
2778 !IndexType::isInstr(
Range.end()))
2782 assert(
SI.mayStore() &&
"Unexpected start instruction");
2784 MachineOperand &SrcOp =
SI.getOperand(2);
2786 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.
getReg(),
2788 auto *RC = HII.getRegClass(
SI.getDesc(), 2);
2805 MachineInstr *CopyIn =
nullptr;
2806 if (SrcRR.
Reg != FoundR || SrcRR.
Sub != 0) {
2808 CopyIn =
BuildMI(
B, StartIt,
DL, HII.get(TargetOpcode::COPY), FoundR)
2814 if (LoxFIs.count(FI) && (&
Range == &RL.back())) {
2817 SrcOp.
setReg(HRI.getSubReg(FoundR, SR));
2829 for (
auto It = StartIt; It != EndIt; It = NextIt) {
2830 MachineInstr &
MI = *It;
2831 NextIt = std::next(It);
2833 if (!HII.isLoadFromStackSlot(
MI, TFI) || TFI != FI)
2836 assert(
MI.getOperand(0).getSubReg() == 0);
2837 MachineInstr *CopyOut =
nullptr;
2838 if (DstR != FoundR) {
2840 unsigned MemSize = HII.getMemAccessSize(
MI);
2842 unsigned CopyOpc = TargetOpcode::COPY;
2843 if (HII.isSignExtendingLoad(
MI))
2844 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2845 else if (HII.isZeroExtendingLoad(
MI))
2846 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2847 CopyOut =
BuildMI(
B, It,
DL, HII.get(CopyOpc), DstR)
2855 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2863void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
MachineFunction &MF,
2864 const HexagonInstrInfo &HII,
2866 MachineBasicBlock &MB = *AI->
getParent();
2876 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2878 if (!NeedsProbing) {
2902 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2906 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), SP)
2944 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2949 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_sub), Rd)
2955 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2964 MF.
insert(InsertPt, LoopMBB);
2966 MF.
insert(InsertPt, ExitMBB);
2977 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2982 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
2988 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
2994 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
3003 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
3007 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_addi), Rd)
3035void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(
MachineInstr *
MI,
3036 const CSIVect &CSI,
bool IsDef,
bool IsKill)
const {
3047 const CSIVect &CSI)
const {
3060 BitVector Regs(Hexagon::NUM_TARGET_REGS);
3063 if (!Hexagon::DoubleRegsRegClass.
contains(R))
3067 int F = Regs.find_first();
3068 if (
F != Hexagon::D8)
3071 int N = Regs.find_next(
F);
3072 if (
N >= 0 &&
N !=
F+1)
3081 const CSIVect &CSI)
const {
3082 if (shouldInlineCSR(MF, CSI))
3084 unsigned NumCSI = CSI.size();
3103 if (HST.getSCSPReg().id() <= MaxReg.id())
3109 return Threshold < NumCSI;
3112bool HexagonFrameLowering::useRestoreFunction(
const MachineFunction &MF,
3113 const CSIVect &CSI)
const {
3114 if (shouldInlineCSR(MF, CSI))
3127 unsigned NumCSI = CSI.size();
3133 return Threshold < NumCSI;
3136bool HexagonFrameLowering::mayOverflowFrameOffset(
MachineFunction &MF)
const {
3141 if (HST.useHVXOps() && StackSize > 256)
3148 bool HasImmStack =
false;
3149 unsigned MinLS = ~0
u;
3151 for (
const MachineBasicBlock &
B : MF) {
3152 for (
const MachineInstr &
MI :
B) {
3154 switch (
MI.getOpcode()) {
3155 case Hexagon::S4_storeirit_io:
3156 case Hexagon::S4_storeirif_io:
3157 case Hexagon::S4_storeiri_io:
3160 case Hexagon::S4_storeirht_io:
3161 case Hexagon::S4_storeirhf_io:
3162 case Hexagon::S4_storeirh_io:
3165 case Hexagon::S4_storeirbt_io:
3166 case Hexagon::S4_storeirbf_io:
3167 case Hexagon::S4_storeirb_io:
3168 if (
MI.getOperand(0).isFI())
3170 MinLS = std::min(MinLS, LS);
3184struct HexagonFrameSortingObject {
3185 bool IsValid =
false;
3191struct HexagonFrameSortingComparator {
3192 inline bool operator()(
const HexagonFrameSortingObject &
A,
3193 const HexagonFrameSortingObject &
B)
const {
3194 return std::make_tuple(!
A.IsValid,
A.ObjectAlignment,
A.Size) <
3195 std::make_tuple(!
B.IsValid,
B.ObjectAlignment,
B.Size);
3205 if (ObjectsToAllocate.
empty())
3209 int NObjects = ObjectsToAllocate.
size();
3217 if (i != ObjectsToAllocate[j])
3228 SortingObjects[i].IsValid =
true;
3229 SortingObjects[i].Index = i;
3239 for (
auto &Obj : SortingObjects) {
3242 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.
MachineRegisterInfo & MRI
This file declares the machine register scavenger class.
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
BitVector & set()
Set all bits in the bitvector.
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
Helper class for creating CFI instructions and inserting them into MIR.
void buildEscape(StringRef Bytes, StringRef Comment="") const
void buildRestore(MCRegister Reg) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool hasOptNone() const
Do not optimize this function (-O0).
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI)
IndexType getIndex(MachineInstr *MI) const
MachineInstr * getInstr(IndexType Idx) const
void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd)
void insertCFIInstructions(MachineFunction &MF) const
bool hasFPImpl(const MachineFunction &MF) const override
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Perform most of the PEI work here:
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Replace a StackProbe stub (if any) with the actual probe code inline.
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
bool needsAligna(const MachineFunction &MF) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
const HexagonRegisterInfo & getRegisterInfo() const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Hexagon target-specific information for each MachineFunction.
Register getStackAlignBaseReg() const
bool isEHReturnCalleeSaveReg(Register Reg) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
bool isEnvironmentMusl() const
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getID() const
getID() - Return the register class ID number.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool hasCalls() const
Return true if the current function has any function calls.
Align getMaxAlign() const
Return alignment of this function's frame.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
BasicBlockListType::iterator iterator
bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
instr_iterator getInstrIterator() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isReturn(QueryType Type=AnyInBundle) const
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
mop_range implicit_operands()
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,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getFixed() const
Returns the fixed component of the stack.
Represent a constant reference to a string, i.e.
LLVM_ABI std::string lower() const
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const TargetRegisterInfo & getRegisterInfo() const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
bool isPositionIndependent() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
unsigned getPosition() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void stable_sort(R &&Range)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonCallFrameInformation()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
MaybeAlign getStackAlign(const Function &F, unsigned Index)
@ End
Run the machine verifier once, at the end of the pipeline.
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
static RegisterSet expandToSubRegs(RegisterRef R, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
std::map< RegisterRef, RangeList > RegToRangeMap
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.